aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c42
1 files changed, 8 insertions, 34 deletions
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 9defc7e14554..0fca7e8abeb7 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -136,49 +136,23 @@ icmpv6_error_message(struct sk_buff *skb,
136{ 136{
137 struct nf_conntrack_tuple intuple, origtuple; 137 struct nf_conntrack_tuple intuple, origtuple;
138 struct nf_conntrack_tuple_hash *h; 138 struct nf_conntrack_tuple_hash *h;
139 struct icmp6hdr _hdr, *hp;
140 unsigned int inip6off;
141 struct nf_conntrack_l4proto *inproto; 139 struct nf_conntrack_l4proto *inproto;
142 u_int8_t inprotonum;
143 unsigned int inprotoff;
144 140
145 NF_CT_ASSERT(skb->nfct == NULL); 141 NF_CT_ASSERT(skb->nfct == NULL);
146 142
147 hp = skb_header_pointer(skb, icmp6off, sizeof(_hdr), &_hdr);
148 if (hp == NULL) {
149 pr_debug("icmpv6_error: Can't get ICMPv6 hdr.\n");
150 return -NF_ACCEPT;
151 }
152
153 inip6off = icmp6off + sizeof(_hdr);
154 if (skb_copy_bits(skb, inip6off+offsetof(struct ipv6hdr, nexthdr),
155 &inprotonum, sizeof(inprotonum)) != 0) {
156 pr_debug("icmpv6_error: Can't get nexthdr in inner IPv6 "
157 "header.\n");
158 return -NF_ACCEPT;
159 }
160 inprotoff = nf_ct_ipv6_skip_exthdr(skb,
161 inip6off + sizeof(struct ipv6hdr),
162 &inprotonum,
163 skb->len - inip6off
164 - sizeof(struct ipv6hdr));
165
166 if ((inprotoff > skb->len) || (inprotonum == NEXTHDR_FRAGMENT)) {
167 pr_debug("icmpv6_error: Can't get protocol header in ICMPv6 "
168 "payload.\n");
169 return -NF_ACCEPT;
170 }
171
172 /* rcu_read_lock()ed by nf_hook_slow */
173 inproto = __nf_ct_l4proto_find(PF_INET6, inprotonum);
174
175 /* Are they talking about one of our connections? */ 143 /* Are they talking about one of our connections? */
176 if (!nf_ct_get_tuple(skb, inip6off, inprotoff, PF_INET6, inprotonum, 144 if (!nf_ct_get_tuplepr(skb,
177 &origtuple, &nf_conntrack_l3proto_ipv6, inproto)) { 145 skb_network_offset(skb)
146 + sizeof(struct ipv6hdr)
147 + sizeof(struct icmp6hdr),
148 PF_INET6, &origtuple)) {
178 pr_debug("icmpv6_error: Can't get tuple\n"); 149 pr_debug("icmpv6_error: Can't get tuple\n");
179 return -NF_ACCEPT; 150 return -NF_ACCEPT;
180 } 151 }
181 152
153 /* rcu_read_lock()ed by nf_hook_slow */
154 inproto = __nf_ct_l4proto_find(PF_INET6, origtuple.dst.protonum);
155
182 /* Ordinarily, we'd expect the inverted tupleproto, but it's 156 /* Ordinarily, we'd expect the inverted tupleproto, but it's
183 been preserved inside the ICMP. */ 157 been preserved inside the ICMP. */
184 if (!nf_ct_invert_tuple(&intuple, &origtuple, 158 if (!nf_ct_invert_tuple(&intuple, &origtuple,