aboutsummaryrefslogtreecommitdiff
path: root/net/xfrm
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm')
-rw-r--r--net/xfrm/xfrm_state.c18
-rw-r--r--net/xfrm/xfrm_user.c18
2 files changed, 25 insertions, 11 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 84bbf8474f3..899de9ed22a 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -505,6 +505,14 @@ __xfrm_state_locate(struct xfrm_state *x, int use_spi, int family)
x->id.proto, family);
}
+static void xfrm_hash_grow_check(int have_hash_collision)
+{
+ if (have_hash_collision &&
+ (xfrm_state_hmask + 1) < xfrm_state_hashmax &&
+ xfrm_state_num > xfrm_state_hmask)
+ schedule_work(&xfrm_hash_work);
+}
+
struct xfrm_state *
xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
struct flowi *fl, struct xfrm_tmpl *tmpl,
@@ -598,6 +606,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES;
x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ;
add_timer(&x->timer);
+ xfrm_state_num++;
+ xfrm_hash_grow_check(x->bydst.next != NULL);
} else {
x->km.state = XFRM_STATE_DEAD;
xfrm_state_put(x);
@@ -614,14 +624,6 @@ out:
return x;
}
-static void xfrm_hash_grow_check(int have_hash_collision)
-{
- if (have_hash_collision &&
- (xfrm_state_hmask + 1) < xfrm_state_hashmax &&
- xfrm_state_num > xfrm_state_hmask)
- schedule_work(&xfrm_hash_work);
-}
-
static void __xfrm_state_insert(struct xfrm_state *x)
{
unsigned int h;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 2b2e59d8ffb..2ee14f8a190 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -323,7 +323,7 @@ static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *
x->props.replay_window = p->replay_window;
x->props.reqid = p->reqid;
x->props.family = p->family;
- x->props.saddr = p->saddr;
+ memcpy(&x->props.saddr, &p->saddr, sizeof(x->props.saddr));
x->props.flags = p->flags;
}
@@ -495,6 +495,7 @@ static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p,
goto out;
}
+ err = -ESRCH;
x = xfrm_state_lookup_byaddr(&p->daddr, saddr, p->proto,
p->family);
}
@@ -545,7 +546,7 @@ static void copy_to_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p)
memcpy(&p->lft, &x->lft, sizeof(p->lft));
memcpy(&p->curlft, &x->curlft, sizeof(p->curlft));
memcpy(&p->stats, &x->stats, sizeof(p->stats));
- p->saddr = x->props.saddr;
+ memcpy(&p->saddr, &x->props.saddr, sizeof(p->saddr));
p->mode = x->props.mode;
p->replay_window = x->props.replay_window;
p->reqid = x->props.reqid;
@@ -1927,6 +1928,9 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt,
len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire));
len += RTA_SPACE(xfrm_user_sec_ctx_size(xp));
+#ifdef CONFIG_XFRM_SUB_POLICY
+ len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
+#endif
skb = alloc_skb(len, GFP_ATOMIC);
if (skb == NULL)
return -ENOMEM;
@@ -2034,6 +2038,9 @@ static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_eve
len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire));
len += RTA_SPACE(xfrm_user_sec_ctx_size(xp));
+#ifdef CONFIG_XFRM_SUB_POLICY
+ len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
+#endif
skb = alloc_skb(len, GFP_ATOMIC);
if (skb == NULL)
return -ENOMEM;
@@ -2060,6 +2067,9 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *
len += RTA_SPACE(headlen);
headlen = sizeof(*id);
}
+#ifdef CONFIG_XFRM_SUB_POLICY
+ len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
+#endif
len += NLMSG_SPACE(headlen);
skb = alloc_skb(len, GFP_ATOMIC);
@@ -2106,10 +2116,12 @@ static int xfrm_notify_policy_flush(struct km_event *c)
struct nlmsghdr *nlh;
struct sk_buff *skb;
unsigned char *b;
+ int len = 0;
#ifdef CONFIG_XFRM_SUB_POLICY
struct xfrm_userpolicy_type upt;
+ len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
#endif
- int len = NLMSG_LENGTH(0);
+ len += NLMSG_LENGTH(0);
skb = alloc_skb(len, GFP_ATOMIC);
if (skb == NULL)