[NETFILTER]: ip6t_eui64: Fixes calculation of Universal/Local bit
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / net / netfilter / xt_helper.c
CommitLineData
1da177e4
LT
1/* iptables module to match on related connections */
2/*
3 * (C) 2001 Martin Josefsson <gandalf@wlug.westbo.se>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
1da177e4
LT
8 */
9
10#include <linux/module.h>
11#include <linux/skbuff.h>
12#include <linux/netfilter.h>
9fb9cbb1
YK
13#include <net/netfilter/nf_conntrack.h>
14#include <net/netfilter/nf_conntrack_core.h>
15#include <net/netfilter/nf_conntrack_helper.h>
2e4e6a17
HW
16#include <linux/netfilter/x_tables.h>
17#include <linux/netfilter/xt_helper.h>
1da177e4
LT
18
19MODULE_LICENSE("GPL");
20MODULE_AUTHOR("Martin Josefsson <gandalf@netfilter.org>");
21MODULE_DESCRIPTION("iptables helper match module");
2e4e6a17
HW
22MODULE_ALIAS("ipt_helper");
23MODULE_ALIAS("ip6t_helper");
1da177e4 24
1da177e4 25
1d93a9cb 26static bool
9fb9cbb1
YK
27match(const struct sk_buff *skb,
28 const struct net_device *in,
29 const struct net_device *out,
c4986734 30 const struct xt_match *match,
9fb9cbb1
YK
31 const void *matchinfo,
32 int offset,
2e4e6a17 33 unsigned int protoff,
cff533ac 34 bool *hotdrop)
9fb9cbb1 35{
2e4e6a17 36 const struct xt_helper_info *info = matchinfo;
a47362a2
JE
37 const struct nf_conn *ct;
38 const struct nf_conn_help *master_help;
342b7e3c 39 const struct nf_conntrack_helper *helper;
9fb9cbb1 40 enum ip_conntrack_info ctinfo;
1d93a9cb 41 bool ret = info->invert;
601e68e1 42
a47362a2 43 ct = nf_ct_get(skb, &ctinfo);
342b7e3c 44 if (!ct || !ct->master)
9fb9cbb1 45 return ret;
9fb9cbb1 46
dc808fe2 47 master_help = nfct_help(ct->master);
342b7e3c
PM
48 if (!master_help)
49 return ret;
9fb9cbb1 50
342b7e3c
PM
51 /* rcu_read_lock()ed by nf_hook_slow */
52 helper = rcu_dereference(master_help->helper);
53 if (!helper)
54 return ret;
9fb9cbb1
YK
55
56 if (info->name[0] == '\0')
1d93a9cb 57 ret = !ret;
9fb9cbb1 58 else
dc808fe2 59 ret ^= !strncmp(master_help->helper->name, info->name,
601e68e1 60 strlen(master_help->helper->name));
9fb9cbb1
YK
61 return ret;
62}
9fb9cbb1 63
ccb79bdc
JE
64static bool check(const char *tablename,
65 const void *inf,
66 const struct xt_match *match,
67 void *matchinfo,
68 unsigned int hook_mask)
1da177e4 69{
2e4e6a17 70 struct xt_helper_info *info = matchinfo;
1da177e4 71
b9f78f9f 72 if (nf_ct_l3proto_try_module_get(match->family) < 0) {
fe0b9294 73 printk(KERN_WARNING "can't load conntrack support for "
b9f78f9f 74 "proto=%d\n", match->family);
ccb79bdc 75 return false;
b9f78f9f 76 }
1da177e4 77 info->name[29] = '\0';
ccb79bdc 78 return true;
1da177e4
LT
79}
80
b9f78f9f 81static void
efa74165 82destroy(const struct xt_match *match, void *matchinfo)
b9f78f9f 83{
b9f78f9f 84 nf_ct_l3proto_module_put(match->family);
b9f78f9f
PNA
85}
86
9f15c530 87static struct xt_match xt_helper_match[] __read_mostly = {
4470bbc7
PM
88 {
89 .name = "helper",
90 .family = AF_INET,
91 .checkentry = check,
92 .match = match,
93 .destroy = destroy,
94 .matchsize = sizeof(struct xt_helper_info),
95 .me = THIS_MODULE,
96 },
97 {
98 .name = "helper",
99 .family = AF_INET6,
100 .checkentry = check,
101 .match = match,
102 .destroy = destroy,
103 .matchsize = sizeof(struct xt_helper_info),
104 .me = THIS_MODULE,
105 },
1da177e4
LT
106};
107
65b4b4e8 108static int __init xt_helper_init(void)
1da177e4 109{
4470bbc7
PM
110 return xt_register_matches(xt_helper_match,
111 ARRAY_SIZE(xt_helper_match));
1da177e4
LT
112}
113
65b4b4e8 114static void __exit xt_helper_fini(void)
1da177e4 115{
4470bbc7 116 xt_unregister_matches(xt_helper_match, ARRAY_SIZE(xt_helper_match));
1da177e4
LT
117}
118
65b4b4e8
AM
119module_init(xt_helper_init);
120module_exit(xt_helper_fini);
1da177e4 121