Blame view

net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c 11.6 KB
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1
2
3
4
5
6
7
8
9
  /*
   * Copyright (C)2004 USAGI/WIDE Project
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   *
   * Author:
   *	Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
10
   */
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
11
12
13
14
15
16
17
18
19
  #include <linux/types.h>
  #include <linux/ipv6.h>
  #include <linux/in6.h>
  #include <linux/netfilter.h>
  #include <linux/module.h>
  #include <linux/skbuff.h>
  #include <linux/icmp.h>
  #include <linux/sysctl.h>
  #include <net/ipv6.h>
04128f233   Pavel Emelyanov   [INET]: Collect c...
20
  #include <net/inet_frag.h>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
21
22
23
24
  
  #include <linux/netfilter_ipv6.h>
  #include <net/netfilter/nf_conntrack.h>
  #include <net/netfilter/nf_conntrack_helper.h>
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
25
  #include <net/netfilter/nf_conntrack_l4proto.h>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
26
27
  #include <net/netfilter/nf_conntrack_l3proto.h>
  #include <net/netfilter/nf_conntrack_core.h>
9d2493f88   Christoph Paasch   netfilter: remove...
28
  #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
29

8ce8439a3   Jan Engelhardt   [NETFILTER]: nf_c...
30
31
  static bool ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
  			      struct nf_conntrack_tuple *tuple)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
32
  {
32948588a   Jan Engelhardt   [NETFILTER]: nf_c...
33
34
  	const u_int32_t *ap;
  	u_int32_t _addrs[8];
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
35
36
37
38
  
  	ap = skb_header_pointer(skb, nhoff + offsetof(struct ipv6hdr, saddr),
  				sizeof(_addrs), _addrs);
  	if (ap == NULL)
8ce8439a3   Jan Engelhardt   [NETFILTER]: nf_c...
39
  		return false;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
40
41
42
  
  	memcpy(tuple->src.u3.ip6, ap, sizeof(tuple->src.u3.ip6));
  	memcpy(tuple->dst.u3.ip6, ap + 4, sizeof(tuple->dst.u3.ip6));
8ce8439a3   Jan Engelhardt   [NETFILTER]: nf_c...
43
  	return true;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
44
  }
8ce8439a3   Jan Engelhardt   [NETFILTER]: nf_c...
45
46
  static bool ipv6_invert_tuple(struct nf_conntrack_tuple *tuple,
  			      const struct nf_conntrack_tuple *orig)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
47
48
49
  {
  	memcpy(tuple->src.u3.ip6, orig->dst.u3.ip6, sizeof(tuple->src.u3.ip6));
  	memcpy(tuple->dst.u3.ip6, orig->src.u3.ip6, sizeof(tuple->dst.u3.ip6));
8ce8439a3   Jan Engelhardt   [NETFILTER]: nf_c...
50
  	return true;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
51
52
53
54
55
  }
  
  static int ipv6_print_tuple(struct seq_file *s,
  			    const struct nf_conntrack_tuple *tuple)
  {
5b095d989   Harvey Harrison   net: replace %p6 ...
56
  	return seq_printf(s, "src=%pI6 dst=%pI6 ",
0c6ce78ab   Harvey Harrison   net: replace uses...
57
  			  tuple->src.u3.ip6, tuple->dst.u3.ip6);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
58
  }
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
  /*
   * Based on ipv6_skip_exthdr() in net/ipv6/exthdr.c
   *
   * This function parses (probably truncated) exthdr set "hdr"
   * of length "len". "nexthdrp" initially points to some place,
   * where type of the first header can be found.
   *
   * It skips all well-known exthdrs, and returns pointer to the start
   * of unparsable area i.e. the first header with unknown type.
   * if success, *nexthdr is updated by type/protocol of this header.
   *
   * NOTES: - it may return pointer pointing beyond end of packet,
   *          if the last recognized header is truncated in the middle.
   *        - if packet is truncated, so that all parsed headers are skipped,
   *          it returns -1.
   *        - if packet is fragmented, return pointer of the fragment header.
   *        - ESP is unparsable for now and considered like
   *          normal payload protocol.
   *        - Note also special handling of AUTH header. Thanks to IPsec wizards.
   */
1a3a206f7   Adrian Bunk   [NETFILTER]: Make...
79
80
  static int nf_ct_ipv6_skip_exthdr(const struct sk_buff *skb, int start,
  				  u8 *nexthdrp, int len)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
  {
  	u8 nexthdr = *nexthdrp;
  
  	while (ipv6_ext_hdr(nexthdr)) {
  		struct ipv6_opt_hdr hdr;
  		int hdrlen;
  
  		if (len < (int)sizeof(struct ipv6_opt_hdr))
  			return -1;
  		if (nexthdr == NEXTHDR_NONE)
  			break;
  		if (nexthdr == NEXTHDR_FRAGMENT)
  			break;
  		if (skb_copy_bits(skb, start, &hdr, sizeof(hdr)))
  			BUG();
  		if (nexthdr == NEXTHDR_AUTH)
  			hdrlen = (hdr.hdrlen+2)<<2;
  		else
  			hdrlen = ipv6_optlen(&hdr);
  
  		nexthdr = hdr.nexthdr;
  		len -= hdrlen;
  		start += hdrlen;
  	}
  
  	*nexthdrp = nexthdr;
  	return start;
  }
ffc306904   Yasuyuki Kozakai   [NETFILTER]: nf_c...
109
110
  static int ipv6_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
  			    unsigned int *dataoff, u_int8_t *protonum)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
111
  {
ffc306904   Yasuyuki Kozakai   [NETFILTER]: nf_c...
112
113
114
115
116
117
118
119
120
121
122
  	unsigned int extoff = nhoff + sizeof(struct ipv6hdr);
  	unsigned char pnum;
  	int protoff;
  
  	if (skb_copy_bits(skb, nhoff + offsetof(struct ipv6hdr, nexthdr),
  			  &pnum, sizeof(pnum)) != 0) {
  		pr_debug("ip6_conntrack_core: can't get nexthdr
  ");
  		return -NF_ACCEPT;
  	}
  	protoff = nf_ct_ipv6_skip_exthdr(skb, extoff, &pnum, skb->len - extoff);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
123
  	/*
ffc306904   Yasuyuki Kozakai   [NETFILTER]: nf_c...
124
  	 * (protoff == skb->len) mean that the packet doesn't have no data
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
125
126
  	 * except of IPv6 & ext headers. but it's tracked anyway. - YK
  	 */
ffc306904   Yasuyuki Kozakai   [NETFILTER]: nf_c...
127
  	if ((protoff < 0) || (protoff > skb->len)) {
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
128
129
  		pr_debug("ip6_conntrack_core: can't find proto in pkt
  ");
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
130
131
132
133
134
135
136
  		return -NF_ACCEPT;
  	}
  
  	*dataoff = protoff;
  	*protonum = pnum;
  	return NF_ACCEPT;
  }
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
137
  static unsigned int ipv6_confirm(unsigned int hooknum,
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
138
  				 struct sk_buff *skb,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
139
140
141
142
143
  				 const struct net_device *in,
  				 const struct net_device *out,
  				 int (*okfn)(struct sk_buff *))
  {
  	struct nf_conn *ct;
32948588a   Jan Engelhardt   [NETFILTER]: nf_c...
144
145
  	const struct nf_conn_help *help;
  	const struct nf_conntrack_helper *helper;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
146
  	enum ip_conntrack_info ctinfo;
dc808fe28   Harald Welte   [NETFILTER] nf_co...
147
  	unsigned int ret, protoff;
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
148
149
  	unsigned int extoff = (u8 *)(ipv6_hdr(skb) + 1) - skb->data;
  	unsigned char pnum = ipv6_hdr(skb)->nexthdr;
dc808fe28   Harald Welte   [NETFILTER] nf_co...
150

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
151
152
  
  	/* This is where we call the helper: as the packet goes out. */
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
153
  	ct = nf_ct_get(skb, &ctinfo);
6442f1cf8   Patrick McHardy   [NETFILTER]: conn...
154
  	if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)
dc808fe28   Harald Welte   [NETFILTER] nf_co...
155
156
157
  		goto out;
  
  	help = nfct_help(ct);
3c158f7f5   Patrick McHarrdy   [NETFILTER]: nf_c...
158
159
160
161
162
  	if (!help)
  		goto out;
  	/* rcu_read_lock()ed by nf_hook_slow */
  	helper = rcu_dereference(help->helper);
  	if (!helper)
dc808fe28   Harald Welte   [NETFILTER] nf_co...
163
  		goto out;
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
164
165
166
  	protoff = nf_ct_ipv6_skip_exthdr(skb, extoff, &pnum,
  					 skb->len - extoff);
  	if (protoff > skb->len || pnum == NEXTHDR_FRAGMENT) {
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
167
168
  		pr_debug("proto header not found
  ");
dc808fe28   Harald Welte   [NETFILTER] nf_co...
169
  		return NF_ACCEPT;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
170
  	}
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
171
  	ret = helper->help(skb, protoff, ct, ctinfo);
dc808fe28   Harald Welte   [NETFILTER] nf_co...
172
173
174
  	if (ret != NF_ACCEPT)
  		return ret;
  out:
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
175
  	/* We've seen it coming out the other side: confirm it */
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
176
  	return nf_conntrack_confirm(skb);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
177
  }
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
178
  static unsigned int ipv6_defrag(unsigned int hooknum,
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
179
  				struct sk_buff *skb,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
180
181
182
183
184
185
186
  				const struct net_device *in,
  				const struct net_device *out,
  				int (*okfn)(struct sk_buff *))
  {
  	struct sk_buff *reasm;
  
  	/* Previously seen (loopback)?  */
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
187
  	if (skb->nfct)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
188
  		return NF_ACCEPT;
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
189
  	reasm = nf_ct_frag6_gather(skb);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
190
191
192
193
194
195
  
  	/* queued */
  	if (reasm == NULL)
  		return NF_STOLEN;
  
  	/* error occured or not fragmented */
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
196
  	if (reasm == skb)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
197
198
199
200
201
202
203
  		return NF_ACCEPT;
  
  	nf_ct_frag6_output(hooknum, reasm, (struct net_device *)in,
  			   (struct net_device *)out, okfn);
  
  	return NF_STOLEN;
  }
a702a65fc   Alexey Dobriyan   netfilter: netns ...
204
205
206
207
  static unsigned int __ipv6_conntrack_in(struct net *net,
  					unsigned int hooknum,
  					struct sk_buff *skb,
  					int (*okfn)(struct sk_buff *))
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
208
  {
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
209
  	struct sk_buff *reasm = skb->nfct_reasm;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
210
211
212
213
214
215
  
  	/* This packet is fragmented and has reassembled packet. */
  	if (reasm) {
  		/* Reassembled packet isn't parsed yet ? */
  		if (!reasm->nfct) {
  			unsigned int ret;
a702a65fc   Alexey Dobriyan   netfilter: netns ...
216
  			ret = nf_conntrack_in(net, PF_INET6, hooknum, reasm);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
217
218
219
220
  			if (ret != NF_ACCEPT)
  				return ret;
  		}
  		nf_conntrack_get(reasm->nfct);
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
221
222
  		skb->nfct = reasm->nfct;
  		skb->nfctinfo = reasm->nfctinfo;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
223
224
  		return NF_ACCEPT;
  	}
a702a65fc   Alexey Dobriyan   netfilter: netns ...
225
226
227
228
229
230
231
232
233
234
  	return nf_conntrack_in(net, PF_INET6, hooknum, skb);
  }
  
  static unsigned int ipv6_conntrack_in(unsigned int hooknum,
  				      struct sk_buff *skb,
  				      const struct net_device *in,
  				      const struct net_device *out,
  				      int (*okfn)(struct sk_buff *))
  {
  	return __ipv6_conntrack_in(dev_net(in), hooknum, skb, okfn);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
235
236
237
  }
  
  static unsigned int ipv6_conntrack_local(unsigned int hooknum,
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
238
  					 struct sk_buff *skb,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
239
240
241
242
243
  					 const struct net_device *in,
  					 const struct net_device *out,
  					 int (*okfn)(struct sk_buff *))
  {
  	/* root is playing with raw sockets. */
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
244
  	if (skb->len < sizeof(struct ipv6hdr)) {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
245
246
247
248
249
  		if (net_ratelimit())
  			printk("ipv6_conntrack_local: packet too short
  ");
  		return NF_ACCEPT;
  	}
a702a65fc   Alexey Dobriyan   netfilter: netns ...
250
  	return __ipv6_conntrack_in(dev_net(out), hooknum, skb, okfn);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
251
  }
1999414a4   Patrick McHardy   [NETFILTER]: Mark...
252
  static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
964ddaa10   Patrick McHardy   [NETFILTER]: Clea...
253
254
255
256
  	{
  		.hook		= ipv6_defrag,
  		.owner		= THIS_MODULE,
  		.pf		= PF_INET6,
6e23ae2a4   Patrick McHardy   [NETFILTER]: Intr...
257
  		.hooknum	= NF_INET_PRE_ROUTING,
964ddaa10   Patrick McHardy   [NETFILTER]: Clea...
258
259
260
261
262
263
  		.priority	= NF_IP6_PRI_CONNTRACK_DEFRAG,
  	},
  	{
  		.hook		= ipv6_conntrack_in,
  		.owner		= THIS_MODULE,
  		.pf		= PF_INET6,
6e23ae2a4   Patrick McHardy   [NETFILTER]: Intr...
264
  		.hooknum	= NF_INET_PRE_ROUTING,
964ddaa10   Patrick McHardy   [NETFILTER]: Clea...
265
266
267
268
269
270
  		.priority	= NF_IP6_PRI_CONNTRACK,
  	},
  	{
  		.hook		= ipv6_conntrack_local,
  		.owner		= THIS_MODULE,
  		.pf		= PF_INET6,
6e23ae2a4   Patrick McHardy   [NETFILTER]: Intr...
271
  		.hooknum	= NF_INET_LOCAL_OUT,
964ddaa10   Patrick McHardy   [NETFILTER]: Clea...
272
273
274
275
276
277
  		.priority	= NF_IP6_PRI_CONNTRACK,
  	},
  	{
  		.hook		= ipv6_defrag,
  		.owner		= THIS_MODULE,
  		.pf		= PF_INET6,
6e23ae2a4   Patrick McHardy   [NETFILTER]: Intr...
278
  		.hooknum	= NF_INET_LOCAL_OUT,
964ddaa10   Patrick McHardy   [NETFILTER]: Clea...
279
280
281
282
283
284
  		.priority	= NF_IP6_PRI_CONNTRACK_DEFRAG,
  	},
  	{
  		.hook		= ipv6_confirm,
  		.owner		= THIS_MODULE,
  		.pf		= PF_INET6,
6e23ae2a4   Patrick McHardy   [NETFILTER]: Intr...
285
  		.hooknum	= NF_INET_POST_ROUTING,
964ddaa10   Patrick McHardy   [NETFILTER]: Clea...
286
287
288
289
290
291
  		.priority	= NF_IP6_PRI_LAST,
  	},
  	{
  		.hook		= ipv6_confirm,
  		.owner		= THIS_MODULE,
  		.pf		= PF_INET6,
6e23ae2a4   Patrick McHardy   [NETFILTER]: Intr...
292
  		.hooknum	= NF_INET_LOCAL_IN,
964ddaa10   Patrick McHardy   [NETFILTER]: Clea...
293
294
  		.priority	= NF_IP6_PRI_LAST-1,
  	},
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
295
  };
e281db5cd   Patrick McHardy   [NETFILTER]: nf_c...
296
  #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
297
298
299
  
  #include <linux/netfilter/nfnetlink.h>
  #include <linux/netfilter/nfnetlink_conntrack.h>
fdf708322   Patrick McHardy   [NETFILTER]: nfne...
300
  static int ipv6_tuple_to_nlattr(struct sk_buff *skb,
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
301
302
  				const struct nf_conntrack_tuple *tuple)
  {
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
303
  	NLA_PUT(skb, CTA_IP_V6_SRC, sizeof(u_int32_t) * 4,
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
304
  		&tuple->src.u3.ip6);
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
305
  	NLA_PUT(skb, CTA_IP_V6_DST, sizeof(u_int32_t) * 4,
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
306
307
  		&tuple->dst.u3.ip6);
  	return 0;
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
308
  nla_put_failure:
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
309
310
  	return -1;
  }
f73e924cd   Patrick McHardy   [NETFILTER]: ctne...
311
312
313
  static const struct nla_policy ipv6_nla_policy[CTA_IP_MAX+1] = {
  	[CTA_IP_V6_SRC]	= { .len = sizeof(u_int32_t)*4 },
  	[CTA_IP_V6_DST]	= { .len = sizeof(u_int32_t)*4 },
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
314
  };
fdf708322   Patrick McHardy   [NETFILTER]: nfne...
315
  static int ipv6_nlattr_to_tuple(struct nlattr *tb[],
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
316
317
  				struct nf_conntrack_tuple *t)
  {
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
318
  	if (!tb[CTA_IP_V6_SRC] || !tb[CTA_IP_V6_DST])
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
319
  		return -EINVAL;
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
320
  	memcpy(&t->src.u3.ip6, nla_data(tb[CTA_IP_V6_SRC]),
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
321
  	       sizeof(u_int32_t) * 4);
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
322
  	memcpy(&t->dst.u3.ip6, nla_data(tb[CTA_IP_V6_DST]),
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
323
324
325
326
327
  	       sizeof(u_int32_t) * 4);
  
  	return 0;
  }
  #endif
61075af51   Patrick McHardy   [NETFILTER]: nf_c...
328
  struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
329
330
331
332
333
  	.l3proto		= PF_INET6,
  	.name			= "ipv6",
  	.pkt_to_tuple		= ipv6_pkt_to_tuple,
  	.invert_tuple		= ipv6_invert_tuple,
  	.print_tuple		= ipv6_print_tuple,
ffc306904   Yasuyuki Kozakai   [NETFILTER]: nf_c...
334
  	.get_l4proto		= ipv6_get_l4proto,
e281db5cd   Patrick McHardy   [NETFILTER]: nf_c...
335
  #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
fdf708322   Patrick McHardy   [NETFILTER]: nfne...
336
337
  	.tuple_to_nlattr	= ipv6_tuple_to_nlattr,
  	.nlattr_to_tuple	= ipv6_nlattr_to_tuple,
f73e924cd   Patrick McHardy   [NETFILTER]: ctne...
338
  	.nla_policy		= ipv6_nla_policy,
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
339
  #endif
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
340
341
342
343
  #ifdef CONFIG_SYSCTL
  	.ctl_table_path		= nf_net_netfilter_sysctl_path,
  	.ctl_table		= nf_ct_ipv6_sysctl_table,
  #endif
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
344
345
  	.me			= THIS_MODULE,
  };
32292a7ff   Patrick McHardy   [NETFILTER]: Fix ...
346
347
348
349
350
  MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6));
  MODULE_LICENSE("GPL");
  MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>");
  
  static int __init nf_conntrack_l3proto_ipv6_init(void)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
351
352
  {
  	int ret = 0;
32292a7ff   Patrick McHardy   [NETFILTER]: Fix ...
353
  	need_conntrack();
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
354
355
356
357
358
  
  	ret = nf_ct_frag6_init();
  	if (ret < 0) {
  		printk("nf_conntrack_ipv6: can't initialize frag6.
  ");
32292a7ff   Patrick McHardy   [NETFILTER]: Fix ...
359
  		return ret;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
360
  	}
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
361
  	ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp6);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
362
363
364
365
366
  	if (ret < 0) {
  		printk("nf_conntrack_ipv6: can't register tcp.
  ");
  		goto cleanup_frag6;
  	}
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
367
  	ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp6);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
368
369
370
371
372
  	if (ret < 0) {
  		printk("nf_conntrack_ipv6: can't register udp.
  ");
  		goto cleanup_tcp;
  	}
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
373
  	ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_icmpv6);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
374
375
376
377
378
379
380
381
382
383
384
385
  	if (ret < 0) {
  		printk("nf_conntrack_ipv6: can't register icmpv6.
  ");
  		goto cleanup_udp;
  	}
  
  	ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv6);
  	if (ret < 0) {
  		printk("nf_conntrack_ipv6: can't register ipv6
  ");
  		goto cleanup_icmpv6;
  	}
964ddaa10   Patrick McHardy   [NETFILTER]: Clea...
386
387
  	ret = nf_register_hooks(ipv6_conntrack_ops,
  				ARRAY_SIZE(ipv6_conntrack_ops));
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
388
389
390
391
392
393
  	if (ret < 0) {
  		printk("nf_conntrack_ipv6: can't register pre-routing defrag "
  		       "hook.
  ");
  		goto cleanup_ipv6;
  	}
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
394
  	return ret;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
395
396
397
   cleanup_ipv6:
  	nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6);
   cleanup_icmpv6:
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
398
  	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
399
   cleanup_udp:
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
400
  	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
401
   cleanup_tcp:
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
402
  	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
403
404
   cleanup_frag6:
  	nf_ct_frag6_cleanup();
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
405
406
  	return ret;
  }
65b4b4e81   Andrew Morton   [NETFILTER]: Rena...
407
  static void __exit nf_conntrack_l3proto_ipv6_fini(void)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
408
  {
32292a7ff   Patrick McHardy   [NETFILTER]: Fix ...
409
  	synchronize_net();
32292a7ff   Patrick McHardy   [NETFILTER]: Fix ...
410
411
  	nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
  	nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6);
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
412
413
414
  	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6);
  	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6);
  	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
32292a7ff   Patrick McHardy   [NETFILTER]: Fix ...
415
  	nf_ct_frag6_cleanup();
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
416
  }
65b4b4e81   Andrew Morton   [NETFILTER]: Rena...
417
418
  module_init(nf_conntrack_l3proto_ipv6_init);
  module_exit(nf_conntrack_l3proto_ipv6_fini);