Commit 668dc8af3150f837f7f0461001bbbc0ce25d7bdf
Committed by
David S. Miller
1 parent
b2aa5e9d43
Exists in
master
and in
39 other branches
[IPSEC]: Move integrity stat collection into xfrm_input
Similar to the moving out of the replay processing on the output, this patch moves the integrity stat collectin from x->type->input into xfrm_input. This would eventually allow transforms such as AH/ESP to be lockless. The error value EBADMSG (currently unused in the crypto layer) is used to indicate a failed integrity check. In future this error can be directly returned by the crypto layer once we switch to aead algorithms. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 5 changed files with 15 additions and 12 deletions Side-by-side Diff
net/ipv4/ah4.c
... | ... | @@ -177,9 +177,8 @@ |
177 | 177 | err = ah_mac_digest(ahp, skb, ah->auth_data); |
178 | 178 | if (err) |
179 | 179 | goto out; |
180 | - err = -EINVAL; | |
181 | 180 | if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len)) { |
182 | - x->stats.integrity_failed++; | |
181 | + err = -EBADMSG; | |
183 | 182 | goto out; |
184 | 183 | } |
185 | 184 | } |
net/ipv4/esp4.c
... | ... | @@ -163,7 +163,7 @@ |
163 | 163 | u8 nexthdr[2]; |
164 | 164 | struct scatterlist *sg; |
165 | 165 | int padlen; |
166 | - int err; | |
166 | + int err = -EINVAL; | |
167 | 167 | |
168 | 168 | if (!pskb_may_pull(skb, sizeof(*esph))) |
169 | 169 | goto out; |
170 | 170 | |
171 | 171 | |
... | ... | @@ -183,13 +183,14 @@ |
183 | 183 | BUG(); |
184 | 184 | |
185 | 185 | if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) { |
186 | - x->stats.integrity_failed++; | |
186 | + err = -EBADMSG; | |
187 | 187 | goto out; |
188 | 188 | } |
189 | 189 | } |
190 | 190 | |
191 | - if ((nfrags = skb_cow_data(skb, 0, &trailer)) < 0) | |
191 | + if ((err = skb_cow_data(skb, 0, &trailer)) < 0) | |
192 | 192 | goto out; |
193 | + nfrags = err; | |
193 | 194 | |
194 | 195 | skb->ip_summed = CHECKSUM_NONE; |
195 | 196 | |
... | ... | @@ -202,6 +203,7 @@ |
202 | 203 | sg = &esp->sgbuf[0]; |
203 | 204 | |
204 | 205 | if (unlikely(nfrags > ESP_NUM_FAST_SG)) { |
206 | + err = -ENOMEM; | |
205 | 207 | sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC); |
206 | 208 | if (!sg) |
207 | 209 | goto out; |
208 | 210 | |
... | ... | @@ -214,11 +216,12 @@ |
214 | 216 | if (unlikely(sg != &esp->sgbuf[0])) |
215 | 217 | kfree(sg); |
216 | 218 | if (unlikely(err)) |
217 | - return err; | |
219 | + goto out; | |
218 | 220 | |
219 | 221 | if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2)) |
220 | 222 | BUG(); |
221 | 223 | |
224 | + err = -EINVAL; | |
222 | 225 | padlen = nexthdr[0]; |
223 | 226 | if (padlen+2 >= elen) |
224 | 227 | goto out; |
... | ... | @@ -276,7 +279,7 @@ |
276 | 279 | return nexthdr[1]; |
277 | 280 | |
278 | 281 | out: |
279 | - return -EINVAL; | |
282 | + return err; | |
280 | 283 | } |
281 | 284 | |
282 | 285 | static u32 esp4_get_mtu(struct xfrm_state *x, int mtu) |
net/ipv6/ah6.c
... | ... | @@ -379,10 +379,9 @@ |
379 | 379 | err = ah_mac_digest(ahp, skb, ah->auth_data); |
380 | 380 | if (err) |
381 | 381 | goto free_out; |
382 | - err = -EINVAL; | |
383 | 382 | if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len)) { |
384 | 383 | LIMIT_NETDEBUG(KERN_WARNING "ipsec ah authentication error\n"); |
385 | - x->stats.integrity_failed++; | |
384 | + err = -EBADMSG; | |
386 | 385 | goto free_out; |
387 | 386 | } |
388 | 387 | } |
net/ipv6/esp6.c
net/xfrm/xfrm_input.c
... | ... | @@ -147,8 +147,11 @@ |
147 | 147 | goto drop_unlock; |
148 | 148 | |
149 | 149 | nexthdr = x->type->input(x, skb); |
150 | - if (nexthdr <= 0) | |
150 | + if (nexthdr <= 0) { | |
151 | + if (nexthdr == -EBADMSG) | |
152 | + x->stats.integrity_failed++; | |
151 | 153 | goto drop_unlock; |
154 | + } | |
152 | 155 | |
153 | 156 | skb_network_header(skb)[nhoff] = nexthdr; |
154 | 157 |