Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
nf_conntrack_proto_generic.c
Go to the documentation of this file.
1 /* (C) 1999-2001 Paul `Rusty' Russell
2  * (C) 2002-2004 Netfilter Core Team <[email protected]>
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>
14 
15 static unsigned int nf_ct_generic_timeout __read_mostly = 600*HZ;
16 
17 static inline struct nf_generic_net *generic_pernet(struct net *net)
18 {
19  return &net->ct.nf_ct_proto.generic;
20 }
21 
22 static bool generic_pkt_to_tuple(const struct sk_buff *skb,
23  unsigned int dataoff,
24  struct nf_conntrack_tuple *tuple)
25 {
26  tuple->src.u.all = 0;
27  tuple->dst.u.all = 0;
28 
29  return true;
30 }
31 
32 static bool generic_invert_tuple(struct nf_conntrack_tuple *tuple,
33  const struct nf_conntrack_tuple *orig)
34 {
35  tuple->src.u.all = 0;
36  tuple->dst.u.all = 0;
37 
38  return true;
39 }
40 
41 /* Print out the per-protocol part of the tuple. */
42 static int generic_print_tuple(struct seq_file *s,
43  const struct nf_conntrack_tuple *tuple)
44 {
45  return 0;
46 }
47 
48 static unsigned int *generic_get_timeouts(struct net *net)
49 {
50  return &(generic_pernet(net)->timeout);
51 }
52 
53 /* Returns verdict for packet, or -1 for invalid. */
54 static int generic_packet(struct nf_conn *ct,
55  const struct sk_buff *skb,
56  unsigned int dataoff,
57  enum ip_conntrack_info ctinfo,
58  u_int8_t pf,
59  unsigned int hooknum,
60  unsigned int *timeout)
61 {
62  nf_ct_refresh_acct(ct, ctinfo, skb, *timeout);
63  return NF_ACCEPT;
64 }
65 
66 /* Called when a new connection for this protocol found. */
67 static bool generic_new(struct nf_conn *ct, const struct sk_buff *skb,
68  unsigned int dataoff, unsigned int *timeouts)
69 {
70  return true;
71 }
72 
73 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
74 
75 #include <linux/netfilter/nfnetlink.h>
77 
78 static int generic_timeout_nlattr_to_obj(struct nlattr *tb[],
79  struct net *net, void *data)
80 {
81  unsigned int *timeout = data;
82  struct nf_generic_net *gn = generic_pernet(net);
83 
85  *timeout =
86  ntohl(nla_get_be32(tb[CTA_TIMEOUT_GENERIC_TIMEOUT])) * HZ;
87  else {
88  /* Set default generic timeout. */
89  *timeout = gn->timeout;
90  }
91 
92  return 0;
93 }
94 
95 static int
96 generic_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data)
97 {
98  const unsigned int *timeout = data;
99 
100  if (nla_put_be32(skb, CTA_TIMEOUT_GENERIC_TIMEOUT, htonl(*timeout / HZ)))
101  goto nla_put_failure;
102 
103  return 0;
104 
105 nla_put_failure:
106  return -ENOSPC;
107 }
108 
109 static const struct nla_policy
110 generic_timeout_nla_policy[CTA_TIMEOUT_GENERIC_MAX+1] = {
112 };
113 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
114 
115 #ifdef CONFIG_SYSCTL
116 static struct ctl_table generic_sysctl_table[] = {
117  {
118  .procname = "nf_conntrack_generic_timeout",
119  .maxlen = sizeof(unsigned int),
120  .mode = 0644,
122  },
123  { }
124 };
125 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
126 static struct ctl_table generic_compat_sysctl_table[] = {
127  {
128  .procname = "ip_conntrack_generic_timeout",
129  .maxlen = sizeof(unsigned int),
130  .mode = 0644,
132  },
133  { }
134 };
135 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
136 #endif /* CONFIG_SYSCTL */
137 
138 static int generic_kmemdup_sysctl_table(struct nf_proto_net *pn,
139  struct nf_generic_net *gn)
140 {
141 #ifdef CONFIG_SYSCTL
142  pn->ctl_table = kmemdup(generic_sysctl_table,
143  sizeof(generic_sysctl_table),
144  GFP_KERNEL);
145  if (!pn->ctl_table)
146  return -ENOMEM;
147 
148  pn->ctl_table[0].data = &gn->timeout;
149 #endif
150  return 0;
151 }
152 
153 static int generic_kmemdup_compat_sysctl_table(struct nf_proto_net *pn,
154  struct nf_generic_net *gn)
155 {
156 #ifdef CONFIG_SYSCTL
157 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
158  pn->ctl_compat_table = kmemdup(generic_compat_sysctl_table,
159  sizeof(generic_compat_sysctl_table),
160  GFP_KERNEL);
161  if (!pn->ctl_compat_table)
162  return -ENOMEM;
163 
164  pn->ctl_compat_table[0].data = &gn->timeout;
165 #endif
166 #endif
167  return 0;
168 }
169 
170 static int generic_init_net(struct net *net, u_int16_t proto)
171 {
172  int ret;
173  struct nf_generic_net *gn = generic_pernet(net);
174  struct nf_proto_net *pn = &gn->pn;
175 
176  gn->timeout = nf_ct_generic_timeout;
177 
178  ret = generic_kmemdup_compat_sysctl_table(pn, gn);
179  if (ret < 0)
180  return ret;
181 
182  ret = generic_kmemdup_sysctl_table(pn, gn);
183  if (ret < 0)
184  nf_ct_kfree_compat_sysctl_table(pn);
185 
186  return ret;
187 }
188 
189 static struct nf_proto_net *generic_get_net_proto(struct net *net)
190 {
191  return &net->ct.nf_ct_proto.generic.pn;
192 }
193 
195 {
196  .l3proto = PF_UNSPEC,
197  .l4proto = 255,
198  .name = "unknown",
199  .pkt_to_tuple = generic_pkt_to_tuple,
200  .invert_tuple = generic_invert_tuple,
201  .print_tuple = generic_print_tuple,
202  .packet = generic_packet,
203  .get_timeouts = generic_get_timeouts,
204  .new = generic_new,
205 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
206  .ctnl_timeout = {
207  .nlattr_to_obj = generic_timeout_nlattr_to_obj,
208  .obj_to_nlattr = generic_timeout_obj_to_nlattr,
209  .nlattr_max = CTA_TIMEOUT_GENERIC_MAX,
210  .obj_size = sizeof(unsigned int),
211  .nla_policy = generic_timeout_nla_policy,
212  },
213 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
214  .init_net = generic_init_net,
215  .get_net_proto = generic_get_net_proto,
216 };