diff options
author | Fan Du <fan.du@windriver.com> | 2013-11-07 04:47:49 -0500 |
---|---|---|
committer | Steffen Klassert <steffen.klassert@secunet.com> | 2013-12-06 00:45:05 -0500 |
commit | 8d549c4f5d92d80fc6f888fd314e10972ae0ec37 (patch) | |
tree | ce8175ec97d47ff6cc6a46360bde3788fca49934 | |
parent | e682adf021be796940be6cc10c07be7f7398c220 (diff) |
xfrm: Using the right namespace to migrate key info
because the home agent could surely be run on a different
net namespace other than init_net. The original behavior
could lead into inconsistent of key info.
Signed-off-by: Fan Du <fan.du@windriver.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
-rw-r--r-- | include/net/xfrm.h | 2 | ||||
-rw-r--r-- | net/key/af_key.c | 3 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 10 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 3 |
4 files changed, 10 insertions, 8 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 6b82fdf4ba71..5b522c5f0188 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -1581,7 +1581,7 @@ struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x, | |||
1581 | struct xfrm_migrate *m); | 1581 | struct xfrm_migrate *m); |
1582 | int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, | 1582 | int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, |
1583 | struct xfrm_migrate *m, int num_bundles, | 1583 | struct xfrm_migrate *m, int num_bundles, |
1584 | struct xfrm_kmaddress *k); | 1584 | struct xfrm_kmaddress *k, struct net *net); |
1585 | #endif | 1585 | #endif |
1586 | 1586 | ||
1587 | int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport); | 1587 | int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport); |
diff --git a/net/key/af_key.c b/net/key/af_key.c index 545f047868ad..3fa811c46913 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -2485,6 +2485,7 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb, | |||
2485 | struct xfrm_selector sel; | 2485 | struct xfrm_selector sel; |
2486 | struct xfrm_migrate m[XFRM_MAX_DEPTH]; | 2486 | struct xfrm_migrate m[XFRM_MAX_DEPTH]; |
2487 | struct xfrm_kmaddress k; | 2487 | struct xfrm_kmaddress k; |
2488 | struct net *net = sock_net(sk); | ||
2488 | 2489 | ||
2489 | if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC - 1], | 2490 | if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC - 1], |
2490 | ext_hdrs[SADB_EXT_ADDRESS_DST - 1]) || | 2491 | ext_hdrs[SADB_EXT_ADDRESS_DST - 1]) || |
@@ -2558,7 +2559,7 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb, | |||
2558 | } | 2559 | } |
2559 | 2560 | ||
2560 | return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i, | 2561 | return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i, |
2561 | kma ? &k : NULL); | 2562 | kma ? &k : NULL, net); |
2562 | 2563 | ||
2563 | out: | 2564 | out: |
2564 | return err; | 2565 | return err; |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index a5bbdfb2874b..907fd2fa70bc 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -3076,14 +3076,14 @@ static bool xfrm_migrate_selector_match(const struct xfrm_selector *sel_cmp, | |||
3076 | } | 3076 | } |
3077 | 3077 | ||
3078 | static struct xfrm_policy * xfrm_migrate_policy_find(const struct xfrm_selector *sel, | 3078 | static struct xfrm_policy * xfrm_migrate_policy_find(const struct xfrm_selector *sel, |
3079 | u8 dir, u8 type) | 3079 | u8 dir, u8 type, struct net *net) |
3080 | { | 3080 | { |
3081 | struct xfrm_policy *pol, *ret = NULL; | 3081 | struct xfrm_policy *pol, *ret = NULL; |
3082 | struct hlist_head *chain; | 3082 | struct hlist_head *chain; |
3083 | u32 priority = ~0U; | 3083 | u32 priority = ~0U; |
3084 | 3084 | ||
3085 | read_lock_bh(&xfrm_policy_lock); | 3085 | read_lock_bh(&xfrm_policy_lock); |
3086 | chain = policy_hash_direct(&init_net, &sel->daddr, &sel->saddr, sel->family, dir); | 3086 | chain = policy_hash_direct(net, &sel->daddr, &sel->saddr, sel->family, dir); |
3087 | hlist_for_each_entry(pol, chain, bydst) { | 3087 | hlist_for_each_entry(pol, chain, bydst) { |
3088 | if (xfrm_migrate_selector_match(sel, &pol->selector) && | 3088 | if (xfrm_migrate_selector_match(sel, &pol->selector) && |
3089 | pol->type == type) { | 3089 | pol->type == type) { |
@@ -3092,7 +3092,7 @@ static struct xfrm_policy * xfrm_migrate_policy_find(const struct xfrm_selector | |||
3092 | break; | 3092 | break; |
3093 | } | 3093 | } |
3094 | } | 3094 | } |
3095 | chain = &init_net.xfrm.policy_inexact[dir]; | 3095 | chain = &net->xfrm.policy_inexact[dir]; |
3096 | hlist_for_each_entry(pol, chain, bydst) { | 3096 | hlist_for_each_entry(pol, chain, bydst) { |
3097 | if (xfrm_migrate_selector_match(sel, &pol->selector) && | 3097 | if (xfrm_migrate_selector_match(sel, &pol->selector) && |
3098 | pol->type == type && | 3098 | pol->type == type && |
@@ -3216,7 +3216,7 @@ static int xfrm_migrate_check(const struct xfrm_migrate *m, int num_migrate) | |||
3216 | 3216 | ||
3217 | int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, | 3217 | int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, |
3218 | struct xfrm_migrate *m, int num_migrate, | 3218 | struct xfrm_migrate *m, int num_migrate, |
3219 | struct xfrm_kmaddress *k) | 3219 | struct xfrm_kmaddress *k, struct net *net) |
3220 | { | 3220 | { |
3221 | int i, err, nx_cur = 0, nx_new = 0; | 3221 | int i, err, nx_cur = 0, nx_new = 0; |
3222 | struct xfrm_policy *pol = NULL; | 3222 | struct xfrm_policy *pol = NULL; |
@@ -3229,7 +3229,7 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, | |||
3229 | goto out; | 3229 | goto out; |
3230 | 3230 | ||
3231 | /* Stage 1 - find policy */ | 3231 | /* Stage 1 - find policy */ |
3232 | if ((pol = xfrm_migrate_policy_find(sel, dir, type)) == NULL) { | 3232 | if ((pol = xfrm_migrate_policy_find(sel, dir, type, net)) == NULL) { |
3233 | err = -ENOENT; | 3233 | err = -ENOENT; |
3234 | goto out; | 3234 | goto out; |
3235 | } | 3235 | } |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 4e0546e9bb0a..840cc8d9fbe4 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -2137,6 +2137,7 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
2137 | u8 type; | 2137 | u8 type; |
2138 | int err; | 2138 | int err; |
2139 | int n = 0; | 2139 | int n = 0; |
2140 | struct net *net = sock_net(skb->sk); | ||
2140 | 2141 | ||
2141 | if (attrs[XFRMA_MIGRATE] == NULL) | 2142 | if (attrs[XFRMA_MIGRATE] == NULL) |
2142 | return -EINVAL; | 2143 | return -EINVAL; |
@@ -2154,7 +2155,7 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
2154 | if (!n) | 2155 | if (!n) |
2155 | return 0; | 2156 | return 0; |
2156 | 2157 | ||
2157 | xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp); | 2158 | xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net); |
2158 | 2159 | ||
2159 | return 0; | 2160 | return 0; |
2160 | } | 2161 | } |