Commit 668dc8af3150f837f7f0461001bbbc0ce25d7bdf

Authored by Herbert Xu
Committed by David S. Miller
1 parent b2aa5e9d43

[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

... ... @@ -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 }
... ... @@ -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)
... ... @@ -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 }
... ... @@ -177,8 +177,7 @@
177 177 BUG();
178 178  
179 179 if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {
180   - x->stats.integrity_failed++;
181   - ret = -EINVAL;
  180 + ret = -EBADMSG;
182 181 goto out;
183 182 }
184 183 }
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