aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/xfrm.h1
-rw-r--r--net/xfrm/xfrm_input.c7
-rw-r--r--net/xfrm/xfrm_output.c1
-rw-r--r--net/xfrm/xfrm_state.c10
-rw-r--r--net/xfrm/xfrm_user.c4
5 files changed, 18 insertions, 5 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 0eb390c205af..da588def3c61 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1552,6 +1552,7 @@ int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
1552 int (*func)(struct xfrm_state *, int, void*), void *); 1552 int (*func)(struct xfrm_state *, int, void*), void *);
1553void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net); 1553void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net);
1554struct xfrm_state *xfrm_state_alloc(struct net *net); 1554struct xfrm_state *xfrm_state_alloc(struct net *net);
1555void xfrm_state_free(struct xfrm_state *x);
1555struct xfrm_state *xfrm_state_find(const xfrm_address_t *daddr, 1556struct xfrm_state *xfrm_state_find(const xfrm_address_t *daddr,
1556 const xfrm_address_t *saddr, 1557 const xfrm_address_t *saddr,
1557 const struct flowi *fl, 1558 const struct flowi *fl,
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 684c0bc01e2c..d5635908587f 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -346,6 +346,12 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
346 346
347 skb->sp->xvec[skb->sp->len++] = x; 347 skb->sp->xvec[skb->sp->len++] = x;
348 348
349 skb_dst_force(skb);
350 if (!skb_dst(skb)) {
351 XFRM_INC_STATS(net, LINUX_MIB_XFRMINERROR);
352 goto drop;
353 }
354
349lock: 355lock:
350 spin_lock(&x->lock); 356 spin_lock(&x->lock);
351 357
@@ -385,7 +391,6 @@ lock:
385 XFRM_SKB_CB(skb)->seq.input.low = seq; 391 XFRM_SKB_CB(skb)->seq.input.low = seq;
386 XFRM_SKB_CB(skb)->seq.input.hi = seq_hi; 392 XFRM_SKB_CB(skb)->seq.input.hi = seq_hi;
387 393
388 skb_dst_force(skb);
389 dev_hold(skb->dev); 394 dev_hold(skb->dev);
390 395
391 if (crypto_done) 396 if (crypto_done)
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 4ae87c5ce2e3..fef6b2da3c5d 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -102,6 +102,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
102 skb_dst_force(skb); 102 skb_dst_force(skb);
103 if (!skb_dst(skb)) { 103 if (!skb_dst(skb)) {
104 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR); 104 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
105 err = -EHOSTUNREACH;
105 goto error_nolock; 106 goto error_nolock;
106 } 107 }
107 108
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index dc4a9f1fb941..23c92891758a 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -426,6 +426,12 @@ static void xfrm_put_mode(struct xfrm_mode *mode)
426 module_put(mode->owner); 426 module_put(mode->owner);
427} 427}
428 428
429void xfrm_state_free(struct xfrm_state *x)
430{
431 kmem_cache_free(xfrm_state_cache, x);
432}
433EXPORT_SYMBOL(xfrm_state_free);
434
429static void xfrm_state_gc_destroy(struct xfrm_state *x) 435static void xfrm_state_gc_destroy(struct xfrm_state *x)
430{ 436{
431 tasklet_hrtimer_cancel(&x->mtimer); 437 tasklet_hrtimer_cancel(&x->mtimer);
@@ -452,7 +458,7 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x)
452 } 458 }
453 xfrm_dev_state_free(x); 459 xfrm_dev_state_free(x);
454 security_xfrm_state_free(x); 460 security_xfrm_state_free(x);
455 kmem_cache_free(xfrm_state_cache, x); 461 xfrm_state_free(x);
456} 462}
457 463
458static void xfrm_state_gc_task(struct work_struct *work) 464static void xfrm_state_gc_task(struct work_struct *work)
@@ -788,7 +794,7 @@ void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si)
788{ 794{
789 spin_lock_bh(&net->xfrm.xfrm_state_lock); 795 spin_lock_bh(&net->xfrm.xfrm_state_lock);
790 si->sadcnt = net->xfrm.state_num; 796 si->sadcnt = net->xfrm.state_num;
791 si->sadhcnt = net->xfrm.state_hmask; 797 si->sadhcnt = net->xfrm.state_hmask + 1;
792 si->sadhmcnt = xfrm_state_hashmax; 798 si->sadhmcnt = xfrm_state_hashmax;
793 spin_unlock_bh(&net->xfrm.xfrm_state_lock); 799 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
794} 800}
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index c9a84e22f5d5..277c1c46fe94 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -2288,13 +2288,13 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
2288 2288
2289 } 2289 }
2290 2290
2291 kfree(x); 2291 xfrm_state_free(x);
2292 kfree(xp); 2292 kfree(xp);
2293 2293
2294 return 0; 2294 return 0;
2295 2295
2296free_state: 2296free_state:
2297 kfree(x); 2297 xfrm_state_free(x);
2298nomem: 2298nomem:
2299 return err; 2299 return err;
2300} 2300}