Commit 8dee5c64 authored by Alexey Kuznetsov's avatar Alexey Kuznetsov Committed by James Morris

[IPSEC]: Few changes to keep racoon ISAKMP daemon happy.

parent fb4e6f86
...@@ -272,6 +272,25 @@ void xfrm_policy_kill(struct xfrm_policy *policy) ...@@ -272,6 +272,25 @@ void xfrm_policy_kill(struct xfrm_policy *policy)
write_unlock_bh(&policy->lock); write_unlock_bh(&policy->lock);
} }
/* Generate new index... KAME seems to generate them ordered by cost
* of an absolute inpredictability of ordering of rules. This will not pass. */
static u32 xfrm_gen_index(int dir)
{
u32 idx;
struct xfrm_policy *p;
static u32 pol_id;
for (;;) {
idx = (++pol_id ? : ++pol_id);
for (p = xfrm_policy_list[dir]; p; p = p->next) {
if (p->index == idx)
break;
}
if (!p)
return idx;
}
}
int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
{ {
struct xfrm_policy *pol, **p; struct xfrm_policy *pol, **p;
...@@ -290,6 +309,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) ...@@ -290,6 +309,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
policy->next = pol ? pol->next : NULL; policy->next = pol ? pol->next : NULL;
*p = policy; *p = policy;
xfrm_policy_genid++; xfrm_policy_genid++;
policy->index = pol ? pol->index : xfrm_gen_index(dir);
write_unlock_bh(&xfrm_policy_lock); write_unlock_bh(&xfrm_policy_lock);
if (pol) { if (pol) {
......
...@@ -274,13 +274,13 @@ static inline void pfkey_hdr_dup(struct sadb_msg *new, struct sadb_msg *orig) ...@@ -274,13 +274,13 @@ static inline void pfkey_hdr_dup(struct sadb_msg *new, struct sadb_msg *orig)
*new = *orig; *new = *orig;
} }
static void pfkey_error(struct sadb_msg *orig, int err) static int pfkey_error(struct sadb_msg *orig, int err, struct sock *sk)
{ {
struct sk_buff *skb = alloc_skb(sizeof(struct sadb_msg) + 16, GFP_KERNEL); struct sk_buff *skb = alloc_skb(sizeof(struct sadb_msg) + 16, GFP_KERNEL);
struct sadb_msg *hdr; struct sadb_msg *hdr;
if (!skb) if (!skb)
return; return -ENOBUFS;
/* Woe be to the platform trying to support PFKEY yet /* Woe be to the platform trying to support PFKEY yet
* having normal errnos outside the 1-255 range, inclusive. * having normal errnos outside the 1-255 range, inclusive.
...@@ -301,7 +301,9 @@ static void pfkey_error(struct sadb_msg *orig, int err) ...@@ -301,7 +301,9 @@ static void pfkey_error(struct sadb_msg *orig, int err)
hdr->sadb_msg_len = (sizeof(struct sadb_msg) / hdr->sadb_msg_len = (sizeof(struct sadb_msg) /
sizeof(uint64_t)); sizeof(uint64_t));
pfkey_broadcast(skb, GFP_KERNEL, BROADCAST_ALL, NULL); pfkey_broadcast(skb, GFP_KERNEL, BROADCAST_ONE, sk);
return 0;
} }
static u8 sadb_ext_min_len[] = { static u8 sadb_ext_min_len[] = {
...@@ -716,7 +718,7 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys, ...@@ -716,7 +718,7 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
struct algo_desc *a = ealg_get_byname(x->ealg->alg_name); struct algo_desc *a = ealg_get_byname(x->ealg->alg_name);
sa->sadb_sa_encrypt = a ? a->desc.sadb_alg_id : 0; sa->sadb_sa_encrypt = a ? a->desc.sadb_alg_id : 0;
} }
sa->sadb_sa_flags = SADB_SAFLAGS_PFS; sa->sadb_sa_flags = 0;
/* hard time */ /* hard time */
if (hsc & 2) { if (hsc & 2) {
...@@ -1538,6 +1540,7 @@ static struct sk_buff * pfkey_xfrm_policy2msg(struct xfrm_policy *xp, int dir) ...@@ -1538,6 +1540,7 @@ static struct sk_buff * pfkey_xfrm_policy2msg(struct xfrm_policy *xp, int dir)
} }
} }
hdr->sadb_msg_len = size / sizeof(uint64_t); hdr->sadb_msg_len = size / sizeof(uint64_t);
hdr->sadb_msg_reserved = atomic_read(&xp->refcnt);
return skb; return skb;
} }
...@@ -1638,7 +1641,6 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h ...@@ -1638,7 +1641,6 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
out_hdr->sadb_msg_type = hdr->sadb_msg_type; out_hdr->sadb_msg_type = hdr->sadb_msg_type;
out_hdr->sadb_msg_satype = 0; out_hdr->sadb_msg_satype = 0;
out_hdr->sadb_msg_errno = 0; out_hdr->sadb_msg_errno = 0;
out_hdr->sadb_msg_reserved = 0;
out_hdr->sadb_msg_seq = hdr->sadb_msg_seq; out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;
out_hdr->sadb_msg_pid = hdr->sadb_msg_pid; out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;
pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, sk); pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, sk);
...@@ -1703,7 +1705,6 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg ...@@ -1703,7 +1705,6 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
out_hdr->sadb_msg_type = SADB_X_SPDDELETE; out_hdr->sadb_msg_type = SADB_X_SPDDELETE;
out_hdr->sadb_msg_satype = 0; out_hdr->sadb_msg_satype = 0;
out_hdr->sadb_msg_errno = 0; out_hdr->sadb_msg_errno = 0;
out_hdr->sadb_msg_reserved = 0;
out_hdr->sadb_msg_seq = hdr->sadb_msg_seq; out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;
out_hdr->sadb_msg_pid = hdr->sadb_msg_pid; out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;
pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, sk); pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, sk);
...@@ -1750,7 +1751,6 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h ...@@ -1750,7 +1751,6 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
out_hdr->sadb_msg_type = hdr->sadb_msg_type; out_hdr->sadb_msg_type = hdr->sadb_msg_type;
out_hdr->sadb_msg_satype = 0; out_hdr->sadb_msg_satype = 0;
out_hdr->sadb_msg_errno = 0; out_hdr->sadb_msg_errno = 0;
out_hdr->sadb_msg_reserved = 0;
out_hdr->sadb_msg_seq = hdr->sadb_msg_seq; out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;
out_hdr->sadb_msg_pid = hdr->sadb_msg_pid; out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;
pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, sk); pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, sk);
...@@ -1780,7 +1780,6 @@ static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr) ...@@ -1780,7 +1780,6 @@ static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr)
out_hdr->sadb_msg_type = SADB_X_SPDDUMP; out_hdr->sadb_msg_type = SADB_X_SPDDUMP;
out_hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC; out_hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC;
out_hdr->sadb_msg_errno = 0; out_hdr->sadb_msg_errno = 0;
out_hdr->sadb_msg_reserved = 0;
out_hdr->sadb_msg_seq = count; out_hdr->sadb_msg_seq = count;
out_hdr->sadb_msg_pid = data->hdr->sadb_msg_pid; out_hdr->sadb_msg_pid = data->hdr->sadb_msg_pid;
pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, data->sk); pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, data->sk);
...@@ -1995,7 +1994,7 @@ static int pfkey_send_notify(struct xfrm_state *x, int hard) ...@@ -1995,7 +1994,7 @@ static int pfkey_send_notify(struct xfrm_state *x, int hard)
out_hdr->sadb_msg_seq = 0; out_hdr->sadb_msg_seq = 0;
out_hdr->sadb_msg_pid = 0; out_hdr->sadb_msg_pid = 0;
pfkey_broadcast(out_skb, GFP_KERNEL, BROADCAST_REGISTERED, NULL); pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL);
return 0; return 0;
} }
...@@ -2166,8 +2165,8 @@ static int pfkey_sendmsg(struct kiocb *kiocb, ...@@ -2166,8 +2165,8 @@ static int pfkey_sendmsg(struct kiocb *kiocb,
err = pfkey_process(sk, skb, hdr); err = pfkey_process(sk, skb, hdr);
out: out:
if (err && hdr) if (err && hdr && pfkey_error(hdr, err, sk) == 0)
pfkey_error(hdr, err); err = 0;
if (skb) if (skb)
kfree_skb(skb); kfree_skb(skb);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment