[NETFILTER]: nf_conntrack: support for layer 3 protocol load on demand
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / net / netfilter / xt_state.c
CommitLineData
1da177e4
LT
1/* Kernel module to match connection tracking information. */
2
3/* (C) 1999-2001 Paul `Rusty' Russell
2e4e6a17 4 * (C) 2002-2005 Netfilter Core Team <coreteam@netfilter.org>
1da177e4
LT
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12#include <linux/skbuff.h>
9fb9cbb1 13#include <net/netfilter/nf_conntrack_compat.h>
2e4e6a17
HW
14#include <linux/netfilter/x_tables.h>
15#include <linux/netfilter/xt_state.h>
1da177e4
LT
16
17MODULE_LICENSE("GPL");
18MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>");
2e4e6a17
HW
19MODULE_DESCRIPTION("ip[6]_tables connection tracking state match module");
20MODULE_ALIAS("ipt_state");
21MODULE_ALIAS("ip6t_state");
1da177e4
LT
22
23static int
24match(const struct sk_buff *skb,
25 const struct net_device *in,
26 const struct net_device *out,
c4986734 27 const struct xt_match *match,
1da177e4
LT
28 const void *matchinfo,
29 int offset,
2e4e6a17 30 unsigned int protoff,
1da177e4
LT
31 int *hotdrop)
32{
2e4e6a17 33 const struct xt_state_info *sinfo = matchinfo;
1da177e4
LT
34 enum ip_conntrack_info ctinfo;
35 unsigned int statebit;
36
9fb9cbb1 37 if (nf_ct_is_untracked(skb))
2e4e6a17 38 statebit = XT_STATE_UNTRACKED;
9fb9cbb1 39 else if (!nf_ct_get_ctinfo(skb, &ctinfo))
2e4e6a17 40 statebit = XT_STATE_INVALID;
1da177e4 41 else
2e4e6a17 42 statebit = XT_STATE_BIT(ctinfo);
1da177e4
LT
43
44 return (sinfo->statemask & statebit);
45}
46
b9f78f9f
PNA
47static int check(const char *tablename,
48 const void *inf,
49 const struct xt_match *match,
50 void *matchinfo,
51 unsigned int matchsize,
52 unsigned int hook_mask)
53{
54#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
55 if (nf_ct_l3proto_try_module_get(match->family) < 0) {
56 printk(KERN_WARNING "can't load nf_conntrack support for "
57 "proto=%d\n", match->family);
58 return 0;
59 }
60#endif
61 return 1;
62}
63
64static void
65destroy(const struct xt_match *match, void *matchinfo, unsigned int matchsize)
66{
67#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
68 nf_ct_l3proto_module_put(match->family);
69#endif
70}
71
2e4e6a17
HW
72static struct xt_match state_match = {
73 .name = "state",
5d04bff0 74 .match = match,
b9f78f9f
PNA
75 .checkentry = check,
76 .destroy = destroy,
5d04bff0 77 .matchsize = sizeof(struct xt_state_info),
a45049c5 78 .family = AF_INET,
2e4e6a17
HW
79 .me = THIS_MODULE,
80};
81
82static struct xt_match state6_match = {
1da177e4 83 .name = "state",
5d04bff0 84 .match = match,
b9f78f9f
PNA
85 .checkentry = check,
86 .destroy = destroy,
5d04bff0 87 .matchsize = sizeof(struct xt_state_info),
a45049c5 88 .family = AF_INET6,
1da177e4
LT
89 .me = THIS_MODULE,
90};
91
92static int __init init(void)
93{
2e4e6a17
HW
94 int ret;
95
96 need_conntrack();
97
a45049c5 98 ret = xt_register_match(&state_match);
2e4e6a17
HW
99 if (ret < 0)
100 return ret;
101
a45049c5 102 ret = xt_register_match(&state6_match);
2e4e6a17 103 if (ret < 0)
a45049c5 104 xt_unregister_match(&state_match);
2e4e6a17
HW
105
106 return ret;
1da177e4
LT
107}
108
109static void __exit fini(void)
110{
a45049c5
PNA
111 xt_unregister_match(&state_match);
112 xt_unregister_match(&state6_match);
1da177e4
LT
113}
114
115module_init(init);
116module_exit(fini);