aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2006-01-05 15:19:05 -0500
committerDavid S. Miller <davem@davemloft.net>2006-01-05 15:19:05 -0500
commitc1d10adb4a521de5760112853f42aaeefcec96eb (patch)
treec7ba283aa0b9016c8403fa6589b7b3418f71acda /net/ipv6
parent205d67c7d942c057648148fefb17e46f77e3efd6 (diff)
[NETFILTER]: Add ctnetlink port for nf_conntrack
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c47
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c77
2 files changed, 115 insertions, 9 deletions
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 753a3ae8502b..704fbbe74874 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -401,6 +401,48 @@ static ctl_table nf_ct_net_table[] = {
401}; 401};
402#endif 402#endif
403 403
404#if defined(CONFIG_NF_CT_NETLINK) || \
405 defined(CONFIG_NF_CT_NETLINK_MODULE)
406
407#include <linux/netfilter/nfnetlink.h>
408#include <linux/netfilter/nfnetlink_conntrack.h>
409
410static int ipv6_tuple_to_nfattr(struct sk_buff *skb,
411 const struct nf_conntrack_tuple *tuple)
412{
413 NFA_PUT(skb, CTA_IP_V6_SRC, sizeof(u_int32_t) * 4,
414 &tuple->src.u3.ip6);
415 NFA_PUT(skb, CTA_IP_V6_DST, sizeof(u_int32_t) * 4,
416 &tuple->dst.u3.ip6);
417 return 0;
418
419nfattr_failure:
420 return -1;
421}
422
423static const size_t cta_min_ip[CTA_IP_MAX] = {
424 [CTA_IP_V6_SRC-1] = sizeof(u_int32_t)*4,
425 [CTA_IP_V6_DST-1] = sizeof(u_int32_t)*4,
426};
427
428static int ipv6_nfattr_to_tuple(struct nfattr *tb[],
429 struct nf_conntrack_tuple *t)
430{
431 if (!tb[CTA_IP_V6_SRC-1] || !tb[CTA_IP_V6_DST-1])
432 return -EINVAL;
433
434 if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip))
435 return -EINVAL;
436
437 memcpy(&t->src.u3.ip6, NFA_DATA(tb[CTA_IP_V6_SRC-1]),
438 sizeof(u_int32_t) * 4);
439 memcpy(&t->dst.u3.ip6, NFA_DATA(tb[CTA_IP_V6_DST-1]),
440 sizeof(u_int32_t) * 4);
441
442 return 0;
443}
444#endif
445
404struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 = { 446struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 = {
405 .l3proto = PF_INET6, 447 .l3proto = PF_INET6,
406 .name = "ipv6", 448 .name = "ipv6",
@@ -409,6 +451,11 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 = {
409 .print_tuple = ipv6_print_tuple, 451 .print_tuple = ipv6_print_tuple,
410 .print_conntrack = ipv6_print_conntrack, 452 .print_conntrack = ipv6_print_conntrack,
411 .prepare = ipv6_prepare, 453 .prepare = ipv6_prepare,
454#if defined(CONFIG_NF_CT_NETLINK) || \
455 defined(CONFIG_NF_CT_NETLINK_MODULE)
456 .tuple_to_nfattr = ipv6_tuple_to_nfattr,
457 .nfattr_to_tuple = ipv6_nfattr_to_tuple,
458#endif
412 .get_features = ipv6_get_features, 459 .get_features = ipv6_get_features,
413 .me = THIS_MODULE, 460 .me = THIS_MODULE,
414}; 461};
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index a7e03cfacd06..09945c333055 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -57,17 +57,17 @@ static int icmpv6_pkt_to_tuple(const struct sk_buff *skb,
57 return 1; 57 return 1;
58} 58}
59 59
60/* Add 1; spaces filled with 0. */
61static u_int8_t invmap[] = {
62 [ICMPV6_ECHO_REQUEST - 128] = ICMPV6_ECHO_REPLY + 1,
63 [ICMPV6_ECHO_REPLY - 128] = ICMPV6_ECHO_REQUEST + 1,
64 [ICMPV6_NI_QUERY - 128] = ICMPV6_NI_QUERY + 1,
65 [ICMPV6_NI_REPLY - 128] = ICMPV6_NI_REPLY +1
66};
67
60static int icmpv6_invert_tuple(struct nf_conntrack_tuple *tuple, 68static int icmpv6_invert_tuple(struct nf_conntrack_tuple *tuple,
61 const struct nf_conntrack_tuple *orig) 69 const struct nf_conntrack_tuple *orig)
62{ 70{
63 /* Add 1; spaces filled with 0. */
64 static u_int8_t invmap[] = {
65 [ICMPV6_ECHO_REQUEST - 128] = ICMPV6_ECHO_REPLY + 1,
66 [ICMPV6_ECHO_REPLY - 128] = ICMPV6_ECHO_REQUEST + 1,
67 [ICMPV6_NI_QUERY - 128] = ICMPV6_NI_QUERY + 1,
68 [ICMPV6_NI_REPLY - 128] = ICMPV6_NI_REPLY +1
69 };
70
71 int type = orig->dst.u.icmp.type - 128; 71 int type = orig->dst.u.icmp.type - 128;
72 if (type < 0 || type >= sizeof(invmap) || !invmap[type]) 72 if (type < 0 || type >= sizeof(invmap) || !invmap[type])
73 return 0; 73 return 0;
@@ -185,7 +185,7 @@ icmpv6_error_message(struct sk_buff *skb,
185 return -NF_ACCEPT; 185 return -NF_ACCEPT;
186 } 186 }
187 187
188 inproto = nf_ct_find_proto(PF_INET6, inprotonum); 188 inproto = __nf_ct_proto_find(PF_INET6, inprotonum);
189 189
190 /* Are they talking about one of our connections? */ 190 /* Are they talking about one of our connections? */
191 if (!nf_ct_get_tuple(skb, inip6off, inprotoff, PF_INET6, inprotonum, 191 if (!nf_ct_get_tuple(skb, inip6off, inprotoff, PF_INET6, inprotonum,
@@ -255,6 +255,60 @@ skipped:
255 return icmpv6_error_message(skb, dataoff, ctinfo, hooknum); 255 return icmpv6_error_message(skb, dataoff, ctinfo, hooknum);
256} 256}
257 257
258#if defined(CONFIG_NF_CT_NETLINK) || \
259 defined(CONFIG_NF_CT_NETLINK_MODULE)
260
261#include <linux/netfilter/nfnetlink.h>
262#include <linux/netfilter/nfnetlink_conntrack.h>
263static int icmpv6_tuple_to_nfattr(struct sk_buff *skb,
264 const struct nf_conntrack_tuple *t)
265{
266 NFA_PUT(skb, CTA_PROTO_ICMPV6_ID, sizeof(u_int16_t),
267 &t->src.u.icmp.id);
268 NFA_PUT(skb, CTA_PROTO_ICMPV6_TYPE, sizeof(u_int8_t),
269 &t->dst.u.icmp.type);
270 NFA_PUT(skb, CTA_PROTO_ICMPV6_CODE, sizeof(u_int8_t),
271 &t->dst.u.icmp.code);
272
273 return 0;
274
275nfattr_failure:
276 return -1;
277}
278
279static const size_t cta_min_proto[CTA_PROTO_MAX] = {
280 [CTA_PROTO_ICMPV6_TYPE-1] = sizeof(u_int8_t),
281 [CTA_PROTO_ICMPV6_CODE-1] = sizeof(u_int8_t),
282 [CTA_PROTO_ICMPV6_ID-1] = sizeof(u_int16_t)
283};
284
285static int icmpv6_nfattr_to_tuple(struct nfattr *tb[],
286 struct nf_conntrack_tuple *tuple)
287{
288 if (!tb[CTA_PROTO_ICMPV6_TYPE-1]
289 || !tb[CTA_PROTO_ICMPV6_CODE-1]
290 || !tb[CTA_PROTO_ICMPV6_ID-1])
291 return -EINVAL;
292
293 if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto))
294 return -EINVAL;
295
296 tuple->dst.u.icmp.type =
297 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_TYPE-1]);
298 tuple->dst.u.icmp.code =
299 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_CODE-1]);
300 tuple->src.u.icmp.id =
301 *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_ID-1]);
302
303 if (tuple->dst.u.icmp.type < 128
304 || tuple->dst.u.icmp.type - 128 >= sizeof(invmap)
305 || !invmap[tuple->dst.u.icmp.type - 128])
306 return -EINVAL;
307
308 return 0;
309}
310#endif
311
258struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6 = 312struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6 =
259{ 313{
260 .l3proto = PF_INET6, 314 .l3proto = PF_INET6,
@@ -267,6 +321,11 @@ struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6 =
267 .packet = icmpv6_packet, 321 .packet = icmpv6_packet,
268 .new = icmpv6_new, 322 .new = icmpv6_new,
269 .error = icmpv6_error, 323 .error = icmpv6_error,
324#if defined(CONFIG_NF_CT_NETLINK) || \
325 defined(CONFIG_NF_CT_NETLINK_MODULE)
326 .tuple_to_nfattr = icmpv6_tuple_to_nfattr,
327 .nfattr_to_tuple = icmpv6_nfattr_to_tuple,
328#endif
270}; 329};
271 330
272EXPORT_SYMBOL(nf_conntrack_protocol_icmpv6); 331EXPORT_SYMBOL(nf_conntrack_protocol_icmpv6);