Commit 0ce490ad4387a67ee8ca5253476272d508fc0b6f

Authored by Gao feng
Committed by Pablo Neira Ayuso
1 parent d2ba1fde42

netfilter: nf_ct_udp: add namespace support

This patch adds namespace support for UDP protocol tracker.

Acked-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

Showing 3 changed files with 103 additions and 11 deletions Side-by-side Diff

include/net/netns/conntrack.h
... ... @@ -34,9 +34,21 @@
34 34 unsigned int tcp_max_retrans;
35 35 };
36 36  
  37 +enum udp_conntrack {
  38 + UDP_CT_UNREPLIED,
  39 + UDP_CT_REPLIED,
  40 + UDP_CT_MAX
  41 +};
  42 +
  43 +struct nf_udp_net {
  44 + struct nf_proto_net pn;
  45 + unsigned int timeouts[UDP_CT_MAX];
  46 +};
  47 +
37 48 struct nf_ip_net {
38 49 struct nf_generic_net generic;
39 50 struct nf_tcp_net tcp;
  51 + struct nf_udp_net udp;
40 52 #if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
41 53 struct ctl_table_header *ctl_table_header;
42 54 struct ctl_table *ctl_table;
net/netfilter/nf_conntrack_proto.c
... ... @@ -305,6 +305,8 @@
305 305 switch (l4proto->l4proto) {
306 306 case IPPROTO_TCP:
307 307 return (struct nf_proto_net *)&net->ct.nf_ct_proto.tcp;
  308 + case IPPROTO_UDP:
  309 + return (struct nf_proto_net *)&net->ct.nf_ct_proto.udp;
308 310 case 255: /* l4proto_generic */
309 311 return (struct nf_proto_net *)&net->ct.nf_ct_proto.generic;
310 312 default:
net/netfilter/nf_conntrack_proto_udp.c
... ... @@ -25,17 +25,16 @@
25 25 #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
26 26 #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
27 27  
28   -enum udp_conntrack {
29   - UDP_CT_UNREPLIED,
30   - UDP_CT_REPLIED,
31   - UDP_CT_MAX
32   -};
33   -
34 28 static unsigned int udp_timeouts[UDP_CT_MAX] = {
35 29 [UDP_CT_UNREPLIED] = 30*HZ,
36 30 [UDP_CT_REPLIED] = 180*HZ,
37 31 };
38 32  
  33 +static inline struct nf_udp_net *udp_pernet(struct net *net)
  34 +{
  35 + return &net->ct.nf_ct_proto.udp;
  36 +}
  37 +
39 38 static bool udp_pkt_to_tuple(const struct sk_buff *skb,
40 39 unsigned int dataoff,
41 40 struct nf_conntrack_tuple *tuple)
... ... @@ -73,7 +72,7 @@
73 72  
74 73 static unsigned int *udp_get_timeouts(struct net *net)
75 74 {
76   - return udp_timeouts;
  75 + return udp_pernet(net)->timeouts;
77 76 }
78 77  
79 78 /* Returns verdict for packet, and may modify conntracktype */
80 79  
... ... @@ -205,14 +204,12 @@
205 204 static struct ctl_table udp_sysctl_table[] = {
206 205 {
207 206 .procname = "nf_conntrack_udp_timeout",
208   - .data = &udp_timeouts[UDP_CT_UNREPLIED],
209 207 .maxlen = sizeof(unsigned int),
210 208 .mode = 0644,
211 209 .proc_handler = proc_dointvec_jiffies,
212 210 },
213 211 {
214 212 .procname = "nf_conntrack_udp_timeout_stream",
215   - .data = &udp_timeouts[UDP_CT_REPLIED],
216 213 .maxlen = sizeof(unsigned int),
217 214 .mode = 0644,
218 215 .proc_handler = proc_dointvec_jiffies,
219 216  
... ... @@ -223,14 +220,12 @@
223 220 static struct ctl_table udp_compat_sysctl_table[] = {
224 221 {
225 222 .procname = "ip_conntrack_udp_timeout",
226   - .data = &udp_timeouts[UDP_CT_UNREPLIED],
227 223 .maxlen = sizeof(unsigned int),
228 224 .mode = 0644,
229 225 .proc_handler = proc_dointvec_jiffies,
230 226 },
231 227 {
232 228 .procname = "ip_conntrack_udp_timeout_stream",
233   - .data = &udp_timeouts[UDP_CT_REPLIED],
234 229 .maxlen = sizeof(unsigned int),
235 230 .mode = 0644,
236 231 .proc_handler = proc_dointvec_jiffies,
... ... @@ -240,6 +235,87 @@
240 235 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
241 236 #endif /* CONFIG_SYSCTL */
242 237  
  238 +static int udp_kmemdup_sysctl_table(struct nf_proto_net *pn)
  239 +{
  240 +#ifdef CONFIG_SYSCTL
  241 + struct nf_udp_net *un = (struct nf_udp_net *)pn;
  242 + if (pn->ctl_table)
  243 + return 0;
  244 + pn->ctl_table = kmemdup(udp_sysctl_table,
  245 + sizeof(udp_sysctl_table),
  246 + GFP_KERNEL);
  247 + if (!pn->ctl_table)
  248 + return -ENOMEM;
  249 + pn->ctl_table[0].data = &un->timeouts[UDP_CT_UNREPLIED];
  250 + pn->ctl_table[1].data = &un->timeouts[UDP_CT_REPLIED];
  251 +#endif
  252 + return 0;
  253 +}
  254 +
  255 +static int udp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn)
  256 +{
  257 +#ifdef CONFIG_SYSCTL
  258 +#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
  259 + struct nf_udp_net *un = (struct nf_udp_net *)pn;
  260 + pn->ctl_compat_table = kmemdup(udp_compat_sysctl_table,
  261 + sizeof(udp_compat_sysctl_table),
  262 + GFP_KERNEL);
  263 + if (!pn->ctl_compat_table)
  264 + return -ENOMEM;
  265 +
  266 + pn->ctl_compat_table[0].data = &un->timeouts[UDP_CT_UNREPLIED];
  267 + pn->ctl_compat_table[1].data = &un->timeouts[UDP_CT_REPLIED];
  268 +#endif
  269 +#endif
  270 + return 0;
  271 +}
  272 +
  273 +static void udp_init_net_data(struct nf_udp_net *un)
  274 +{
  275 + int i;
  276 +#ifdef CONFIG_SYSCTL
  277 + if (!un->pn.ctl_table) {
  278 +#else
  279 + if (!un->pn.user++) {
  280 +#endif
  281 + for (i = 0; i < UDP_CT_MAX; i++)
  282 + un->timeouts[i] = udp_timeouts[i];
  283 + }
  284 +}
  285 +
  286 +static int udpv4_init_net(struct net *net)
  287 +{
  288 + int ret;
  289 + struct nf_udp_net *un = udp_pernet(net);
  290 + struct nf_proto_net *pn = (struct nf_proto_net *)un;
  291 +
  292 + udp_init_net_data(un);
  293 +
  294 + ret = udp_kmemdup_compat_sysctl_table(pn);
  295 + if (ret < 0)
  296 + return ret;
  297 +
  298 + ret = udp_kmemdup_sysctl_table(pn);
  299 +#ifdef CONFIG_SYSCTL
  300 +#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
  301 + if (ret < 0) {
  302 + kfree(pn->ctl_compat_table);
  303 + pn->ctl_compat_table = NULL;
  304 + }
  305 +#endif
  306 +#endif
  307 + return ret;
  308 +}
  309 +
  310 +static int udpv6_init_net(struct net *net)
  311 +{
  312 + struct nf_udp_net *un = udp_pernet(net);
  313 + struct nf_proto_net *pn = (struct nf_proto_net *)un;
  314 +
  315 + udp_init_net_data(un);
  316 + return udp_kmemdup_sysctl_table(pn);
  317 +}
  318 +
243 319 struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 __read_mostly =
244 320 {
245 321 .l3proto = PF_INET,
... ... @@ -275,6 +351,7 @@
275 351 .ctl_compat_table = udp_compat_sysctl_table,
276 352 #endif
277 353 #endif
  354 + .init_net = udpv4_init_net,
278 355 };
279 356 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp4);
280 357  
... ... @@ -310,6 +387,7 @@
310 387 .ctl_table_header = &udp_sysctl_header,
311 388 .ctl_table = udp_sysctl_table,
312 389 #endif
  390 + .init_net = udpv6_init_net,
313 391 };
314 392 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp6);