diff options
author | Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp> | 2007-07-14 23:44:50 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-07-14 23:44:50 -0400 |
commit | ffc30690480bdd337e4914302b926d24870b56b2 (patch) | |
tree | 805dfdda135a6f91648aded75b1cfb754705a4b4 | |
parent | d87d8469e2dd19a3a134b99f78288d41854c614b (diff) |
[NETFILTER]: nf_conntrack: make l3proto->prepare() generic and renames it
The icmp[v6] l4proto modules parse headers in ICMP[v6] error to get tuple.
But they have to find the offset to transport protocol header before that.
Their processings are almost same as prepare() of l3proto modules.
This makes prepare() more generic to simplify icmp[v6] l4proto module
later.
Signed-off-by: Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/netfilter/ipv6/nf_conntrack_ipv6.h | 2 | ||||
-rw-r--r-- | include/net/netfilter/nf_conntrack_l3proto.h | 6 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 23 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 27 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_core.c | 5 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_l3proto_generic.c | 7 |
6 files changed, 40 insertions, 30 deletions
diff --git a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h index b4b6049e01fa..5a8965904377 100644 --- a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h +++ b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h | |||
@@ -7,7 +7,7 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6; | |||
7 | extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6; | 7 | extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6; |
8 | extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6; | 8 | extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6; |
9 | 9 | ||
10 | extern int nf_ct_ipv6_skip_exthdr(struct sk_buff *skb, int start, | 10 | extern int nf_ct_ipv6_skip_exthdr(const struct sk_buff *skb, int start, |
11 | u8 *nexthdrp, int len); | 11 | u8 *nexthdrp, int len); |
12 | 12 | ||
13 | extern int nf_ct_frag6_init(void); | 13 | extern int nf_ct_frag6_init(void); |
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h index 890752d7f673..e3708a698d8b 100644 --- a/include/net/netfilter/nf_conntrack_l3proto.h +++ b/include/net/netfilter/nf_conntrack_l3proto.h | |||
@@ -58,11 +58,11 @@ struct nf_conntrack_l3proto | |||
58 | 58 | ||
59 | /* | 59 | /* |
60 | * Called before tracking. | 60 | * Called before tracking. |
61 | * *dataoff: offset of protocol header (TCP, UDP,...) in *pskb | 61 | * *dataoff: offset of protocol header (TCP, UDP,...) in skb |
62 | * *protonum: protocol number | 62 | * *protonum: protocol number |
63 | */ | 63 | */ |
64 | int (*prepare)(struct sk_buff **pskb, unsigned int hooknum, | 64 | int (*get_l4proto)(const struct sk_buff *skb, unsigned int nhoff, |
65 | unsigned int *dataoff, u_int8_t *protonum); | 65 | unsigned int *dataoff, u_int8_t *protonum); |
66 | 66 | ||
67 | int (*tuple_to_nfattr)(struct sk_buff *skb, | 67 | int (*tuple_to_nfattr)(struct sk_buff *skb, |
68 | const struct nf_conntrack_tuple *t); | 68 | const struct nf_conntrack_tuple *t); |
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 3c5629938487..ee29f4e9eac2 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | |||
@@ -78,21 +78,26 @@ nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user) | |||
78 | return skb; | 78 | return skb; |
79 | } | 79 | } |
80 | 80 | ||
81 | static int | 81 | static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, |
82 | ipv4_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff, | 82 | unsigned int *dataoff, u_int8_t *protonum) |
83 | u_int8_t *protonum) | ||
84 | { | 83 | { |
84 | struct iphdr _iph, *iph; | ||
85 | |||
86 | iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph); | ||
87 | if (iph == NULL) | ||
88 | return -NF_DROP; | ||
89 | |||
85 | /* Never happen */ | 90 | /* Never happen */ |
86 | if (ip_hdr(*pskb)->frag_off & htons(IP_OFFSET)) { | 91 | if (iph->frag_off & htons(IP_OFFSET)) { |
87 | if (net_ratelimit()) { | 92 | if (net_ratelimit()) { |
88 | printk(KERN_ERR "ipv4_prepare: Frag of proto %u (hook=%u)\n", | 93 | printk(KERN_ERR "ipv4_get_l4proto: Frag of proto %u\n", |
89 | ip_hdr(*pskb)->protocol, hooknum); | 94 | iph->protocol); |
90 | } | 95 | } |
91 | return -NF_DROP; | 96 | return -NF_DROP; |
92 | } | 97 | } |
93 | 98 | ||
94 | *dataoff = skb_network_offset(*pskb) + ip_hdrlen(*pskb); | 99 | *dataoff = nhoff + (iph->ihl << 2); |
95 | *protonum = ip_hdr(*pskb)->protocol; | 100 | *protonum = iph->protocol; |
96 | 101 | ||
97 | return NF_ACCEPT; | 102 | return NF_ACCEPT; |
98 | } | 103 | } |
@@ -407,7 +412,7 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 = { | |||
407 | .invert_tuple = ipv4_invert_tuple, | 412 | .invert_tuple = ipv4_invert_tuple, |
408 | .print_tuple = ipv4_print_tuple, | 413 | .print_tuple = ipv4_print_tuple, |
409 | .print_conntrack = ipv4_print_conntrack, | 414 | .print_conntrack = ipv4_print_conntrack, |
410 | .prepare = ipv4_prepare, | 415 | .get_l4proto = ipv4_get_l4proto, |
411 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 416 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) |
412 | .tuple_to_nfattr = ipv4_tuple_to_nfattr, | 417 | .tuple_to_nfattr = ipv4_tuple_to_nfattr, |
413 | .nfattr_to_tuple = ipv4_nfattr_to_tuple, | 418 | .nfattr_to_tuple = ipv4_nfattr_to_tuple, |
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index b5c4bb54691e..9b7eaaadc67e 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |||
@@ -86,7 +86,7 @@ static int ipv6_print_conntrack(struct seq_file *s, | |||
86 | * - Note also special handling of AUTH header. Thanks to IPsec wizards. | 86 | * - Note also special handling of AUTH header. Thanks to IPsec wizards. |
87 | */ | 87 | */ |
88 | 88 | ||
89 | int nf_ct_ipv6_skip_exthdr(struct sk_buff *skb, int start, u8 *nexthdrp, | 89 | int nf_ct_ipv6_skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp, |
90 | int len) | 90 | int len) |
91 | { | 91 | { |
92 | u8 nexthdr = *nexthdrp; | 92 | u8 nexthdr = *nexthdrp; |
@@ -117,19 +117,24 @@ int nf_ct_ipv6_skip_exthdr(struct sk_buff *skb, int start, u8 *nexthdrp, | |||
117 | return start; | 117 | return start; |
118 | } | 118 | } |
119 | 119 | ||
120 | static int | 120 | static int ipv6_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, |
121 | ipv6_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff, | 121 | unsigned int *dataoff, u_int8_t *protonum) |
122 | u_int8_t *protonum) | ||
123 | { | 122 | { |
124 | unsigned int extoff = (u8 *)(ipv6_hdr(*pskb) + 1) - (*pskb)->data; | 123 | unsigned int extoff = nhoff + sizeof(struct ipv6hdr); |
125 | unsigned char pnum = ipv6_hdr(*pskb)->nexthdr; | 124 | unsigned char pnum; |
126 | int protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum, | 125 | int protoff; |
127 | (*pskb)->len - extoff); | 126 | |
127 | if (skb_copy_bits(skb, nhoff + offsetof(struct ipv6hdr, nexthdr), | ||
128 | &pnum, sizeof(pnum)) != 0) { | ||
129 | pr_debug("ip6_conntrack_core: can't get nexthdr\n"); | ||
130 | return -NF_ACCEPT; | ||
131 | } | ||
132 | protoff = nf_ct_ipv6_skip_exthdr(skb, extoff, &pnum, skb->len - extoff); | ||
128 | /* | 133 | /* |
129 | * (protoff == (*pskb)->len) mean that the packet doesn't have no data | 134 | * (protoff == skb->len) mean that the packet doesn't have no data |
130 | * except of IPv6 & ext headers. but it's tracked anyway. - YK | 135 | * except of IPv6 & ext headers. but it's tracked anyway. - YK |
131 | */ | 136 | */ |
132 | if ((protoff < 0) || (protoff > (*pskb)->len)) { | 137 | if ((protoff < 0) || (protoff > skb->len)) { |
133 | pr_debug("ip6_conntrack_core: can't find proto in pkt\n"); | 138 | pr_debug("ip6_conntrack_core: can't find proto in pkt\n"); |
134 | return -NF_ACCEPT; | 139 | return -NF_ACCEPT; |
135 | } | 140 | } |
@@ -375,7 +380,7 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 = { | |||
375 | .invert_tuple = ipv6_invert_tuple, | 380 | .invert_tuple = ipv6_invert_tuple, |
376 | .print_tuple = ipv6_print_tuple, | 381 | .print_tuple = ipv6_print_tuple, |
377 | .print_conntrack = ipv6_print_conntrack, | 382 | .print_conntrack = ipv6_print_conntrack, |
378 | .prepare = ipv6_prepare, | 383 | .get_l4proto = ipv6_get_l4proto, |
379 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 384 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) |
380 | .tuple_to_nfattr = ipv6_tuple_to_nfattr, | 385 | .tuple_to_nfattr = ipv6_tuple_to_nfattr, |
381 | .nfattr_to_tuple = ipv6_nfattr_to_tuple, | 386 | .nfattr_to_tuple = ipv6_nfattr_to_tuple, |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index b730413738a6..5b194e3c4e25 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -622,8 +622,9 @@ nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff **pskb) | |||
622 | 622 | ||
623 | /* rcu_read_lock()ed by nf_hook_slow */ | 623 | /* rcu_read_lock()ed by nf_hook_slow */ |
624 | l3proto = __nf_ct_l3proto_find((u_int16_t)pf); | 624 | l3proto = __nf_ct_l3proto_find((u_int16_t)pf); |
625 | 625 | ret = l3proto->get_l4proto(*pskb, skb_network_offset(*pskb), | |
626 | if ((ret = l3proto->prepare(pskb, hooknum, &dataoff, &protonum)) <= 0) { | 626 | &dataoff, &protonum); |
627 | if (ret <= 0) { | ||
627 | pr_debug("not prepared to track yet or error occured\n"); | 628 | pr_debug("not prepared to track yet or error occured\n"); |
628 | NF_CT_STAT_INC_ATOMIC(error); | 629 | NF_CT_STAT_INC_ATOMIC(error); |
629 | NF_CT_STAT_INC_ATOMIC(invalid); | 630 | NF_CT_STAT_INC_ATOMIC(invalid); |
diff --git a/net/netfilter/nf_conntrack_l3proto_generic.c b/net/netfilter/nf_conntrack_l3proto_generic.c index b1bfa207a850..0691642b7724 100644 --- a/net/netfilter/nf_conntrack_l3proto_generic.c +++ b/net/netfilter/nf_conntrack_l3proto_generic.c | |||
@@ -61,9 +61,8 @@ static int generic_print_conntrack(struct seq_file *s, | |||
61 | return 0; | 61 | return 0; |
62 | } | 62 | } |
63 | 63 | ||
64 | static int | 64 | static int generic_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, |
65 | generic_prepare(struct sk_buff **pskb, unsigned int hooknum, | 65 | unsigned int *dataoff, u_int8_t *protonum) |
66 | unsigned int *dataoff, u_int8_t *protonum) | ||
67 | { | 66 | { |
68 | /* Never track !!! */ | 67 | /* Never track !!! */ |
69 | return -NF_ACCEPT; | 68 | return -NF_ACCEPT; |
@@ -77,6 +76,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_generic = { | |||
77 | .invert_tuple = generic_invert_tuple, | 76 | .invert_tuple = generic_invert_tuple, |
78 | .print_tuple = generic_print_tuple, | 77 | .print_tuple = generic_print_tuple, |
79 | .print_conntrack = generic_print_conntrack, | 78 | .print_conntrack = generic_print_conntrack, |
80 | .prepare = generic_prepare, | 79 | .get_l4proto = generic_get_l4proto, |
81 | }; | 80 | }; |
82 | EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_generic); | 81 | EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_generic); |