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 unsigned int nf_ct_generic_timeout __read_mostly = 600*HZ;
  16
  17static bool nf_generic_should_process(u8 proto)
  18{
  19        switch (proto) {
  20#ifdef CONFIG_NF_CT_PROTO_SCTP_MODULE
  21        case IPPROTO_SCTP:
  22                return false;
  23#endif
  24#ifdef CONFIG_NF_CT_PROTO_DCCP_MODULE
  25        case IPPROTO_DCCP:
  26                return false;
  27#endif
  28#ifdef CONFIG_NF_CT_PROTO_GRE_MODULE
  29        case IPPROTO_GRE:
  30                return false;
  31#endif
  32#ifdef CONFIG_NF_CT_PROTO_UDPLITE_MODULE
  33        case IPPROTO_UDPLITE:
  34                return false;
  35#endif
  36        default:
  37                return true;
  38        }
  39}
  40
  41static inline struct nf_generic_net *generic_pernet(struct net *net)
  42{
  43        return &net->ct.nf_ct_proto.generic;
  44}
  45
  46static bool generic_pkt_to_tuple(const struct sk_buff *skb,
  47                                 unsigned int dataoff,
  48                                 struct net *net, struct nf_conntrack_tuple *tuple)
  49{
  50        tuple->src.u.all = 0;
  51        tuple->dst.u.all = 0;
  52
  53        return true;
  54}
  55
  56static bool generic_invert_tuple(struct nf_conntrack_tuple *tuple,
  57                                 const struct nf_conntrack_tuple *orig)
  58{
  59        tuple->src.u.all = 0;
  60        tuple->dst.u.all = 0;
  61
  62        return true;
  63}
  64
  65/* Print out the per-protocol part of the tuple. */
  66static void generic_print_tuple(struct seq_file *s,
  67                                const struct nf_conntrack_tuple *tuple)
  68{
  69}
  70
  71static unsigned int *generic_get_timeouts(struct net *net)
  72{
  73        return &(generic_pernet(net)->timeout);
  74}
  75
  76/* Returns verdict for packet, or -1 for invalid. */
  77static int generic_packet(struct nf_conn *ct,
  78                          const struct sk_buff *skb,
  79                          unsigned int dataoff,
  80                          enum ip_conntrack_info ctinfo,
  81                          u_int8_t pf,
  82                          unsigned int hooknum,
  83                          unsigned int *timeout)
  84{
  85        nf_ct_refresh_acct(ct, ctinfo, skb, *timeout);
  86        return NF_ACCEPT;
  87}
  88
  89/* Called when a new connection for this protocol found. */
  90static bool generic_new(struct nf_conn *ct, const struct sk_buff *skb,
  91                        unsigned int dataoff, unsigned int *timeouts)
  92{
  93        bool ret;
  94
  95        ret = nf_generic_should_process(nf_ct_protonum(ct));
  96        if (!ret)
  97                pr_warn_once("conntrack: generic helper won't handle protocol %d. Please consider loading the specific helper module.\n",
  98                             nf_ct_protonum(ct));
  99        return ret;
 100}
 101
 102#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
 103
 104#include <linux/netfilter/nfnetlink.h>
 105#include <linux/netfilter/nfnetlink_cttimeout.h>
 106
 107static int generic_timeout_nlattr_to_obj(struct nlattr *tb[],
 108                                         struct net *net, void *data)
 109{
 110        unsigned int *timeout = data;
 111        struct nf_generic_net *gn = generic_pernet(net);
 112
 113        if (tb[CTA_TIMEOUT_GENERIC_TIMEOUT])
 114                *timeout =
 115                    ntohl(nla_get_be32(tb[CTA_TIMEOUT_GENERIC_TIMEOUT])) * HZ;
 116        else {
 117                /* Set default generic timeout. */
 118                *timeout = gn->timeout;
 119        }
 120
 121        return 0;
 122}
 123
 124static int
 125generic_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data)
 126{
 127        const unsigned int *timeout = data;
 128
 129        if (nla_put_be32(skb, CTA_TIMEOUT_GENERIC_TIMEOUT, htonl(*timeout / HZ)))
 130                goto nla_put_failure;
 131
 132        return 0;
 133
 134nla_put_failure:
 135        return -ENOSPC;
 136}
 137
 138static const struct nla_policy
 139generic_timeout_nla_policy[CTA_TIMEOUT_GENERIC_MAX+1] = {
 140        [CTA_TIMEOUT_GENERIC_TIMEOUT]   = { .type = NLA_U32 },
 141};
 142#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
 143
 144#ifdef CONFIG_SYSCTL
 145static struct ctl_table generic_sysctl_table[] = {
 146        {
 147                .procname       = "nf_conntrack_generic_timeout",
 148                .maxlen         = sizeof(unsigned int),
 149                .mode           = 0644,
 150                .proc_handler   = proc_dointvec_jiffies,
 151        },
 152        { }
 153};
 154#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
 155static struct ctl_table generic_compat_sysctl_table[] = {
 156        {
 157                .procname       = "ip_conntrack_generic_timeout",
 158                .maxlen         = sizeof(unsigned int),
 159                .mode           = 0644,
 160                .proc_handler   = proc_dointvec_jiffies,
 161        },
 162        { }
 163};
 164#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
 165#endif /* CONFIG_SYSCTL */
 166
 167static int generic_kmemdup_sysctl_table(struct nf_proto_net *pn,
 168                                        struct nf_generic_net *gn)
 169{
 170#ifdef CONFIG_SYSCTL
 171        pn->ctl_table = kmemdup(generic_sysctl_table,
 172                                sizeof(generic_sysctl_table),
 173                                GFP_KERNEL);
 174        if (!pn->ctl_table)
 175                return -ENOMEM;
 176
 177        pn->ctl_table[0].data = &gn->timeout;
 178#endif
 179        return 0;
 180}
 181
 182static int generic_kmemdup_compat_sysctl_table(struct nf_proto_net *pn,
 183                                               struct nf_generic_net *gn)
 184{
 185#ifdef CONFIG_SYSCTL
 186#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
 187        pn->ctl_compat_table = kmemdup(generic_compat_sysctl_table,
 188                                       sizeof(generic_compat_sysctl_table),
 189                                       GFP_KERNEL);
 190        if (!pn->ctl_compat_table)
 191                return -ENOMEM;
 192
 193        pn->ctl_compat_table[0].data = &gn->timeout;
 194#endif
 195#endif
 196        return 0;
 197}
 198
 199static int generic_init_net(struct net *net, u_int16_t proto)
 200{
 201        int ret;
 202        struct nf_generic_net *gn = generic_pernet(net);
 203        struct nf_proto_net *pn = &gn->pn;
 204
 205        gn->timeout = nf_ct_generic_timeout;
 206
 207        ret = generic_kmemdup_compat_sysctl_table(pn, gn);
 208        if (ret < 0)
 209                return ret;
 210
 211        ret = generic_kmemdup_sysctl_table(pn, gn);
 212        if (ret < 0)
 213                nf_ct_kfree_compat_sysctl_table(pn);
 214
 215        return ret;
 216}
 217
 218static struct nf_proto_net *generic_get_net_proto(struct net *net)
 219{
 220        return &net->ct.nf_ct_proto.generic.pn;
 221}
 222
 223struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly =
 224{
 225        .l3proto                = PF_UNSPEC,
 226        .l4proto                = 255,
 227        .name                   = "unknown",
 228        .pkt_to_tuple           = generic_pkt_to_tuple,
 229        .invert_tuple           = generic_invert_tuple,
 230        .print_tuple            = generic_print_tuple,
 231        .packet                 = generic_packet,
 232        .get_timeouts           = generic_get_timeouts,
 233        .new                    = generic_new,
 234#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
 235        .ctnl_timeout           = {
 236                .nlattr_to_obj  = generic_timeout_nlattr_to_obj,
 237                .obj_to_nlattr  = generic_timeout_obj_to_nlattr,
 238                .nlattr_max     = CTA_TIMEOUT_GENERIC_MAX,
 239                .obj_size       = sizeof(unsigned int),
 240                .nla_policy     = generic_timeout_nla_policy,
 241        },
 242#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
 243        .init_net               = generic_init_net,
 244        .get_net_proto          = generic_get_net_proto,
 245};
 246