diff options
Diffstat (limited to 'net')
-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 |
4 files changed, 36 insertions, 26 deletions
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); |