diff options
| -rw-r--r-- | include/net/netns/xfrm.h | 4 | ||||
| -rw-r--r-- | include/net/xfrm.h | 11 | ||||
| -rw-r--r-- | net/key/af_key.c | 15 | ||||
| -rw-r--r-- | net/xfrm/xfrm_policy.c | 104 | ||||
| -rw-r--r-- | net/xfrm/xfrm_state.c | 104 | ||||
| -rw-r--r-- | net/xfrm/xfrm_user.c | 14 |
6 files changed, 138 insertions, 114 deletions
diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h index 5299e69a32af..ea28404e9d79 100644 --- a/include/net/netns/xfrm.h +++ b/include/net/netns/xfrm.h | |||
| @@ -59,6 +59,10 @@ struct netns_xfrm { | |||
| 59 | #if IS_ENABLED(CONFIG_IPV6) | 59 | #if IS_ENABLED(CONFIG_IPV6) |
| 60 | struct dst_ops xfrm6_dst_ops; | 60 | struct dst_ops xfrm6_dst_ops; |
| 61 | #endif | 61 | #endif |
| 62 | spinlock_t xfrm_state_lock; | ||
| 63 | spinlock_t xfrm_policy_sk_bundle_lock; | ||
| 64 | rwlock_t xfrm_policy_lock; | ||
| 65 | struct mutex xfrm_cfg_mutex; | ||
| 62 | }; | 66 | }; |
| 63 | 67 | ||
| 64 | #endif | 68 | #endif |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 5b522c5f0188..59f5d0a6c7f8 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
| @@ -53,7 +53,6 @@ | |||
| 53 | #define XFRM_INC_STATS_USER(net, field) ((void)(net)) | 53 | #define XFRM_INC_STATS_USER(net, field) ((void)(net)) |
| 54 | #endif | 54 | #endif |
| 55 | 55 | ||
| 56 | extern struct mutex xfrm_cfg_mutex; | ||
| 57 | 56 | ||
| 58 | /* Organization of SPD aka "XFRM rules" | 57 | /* Organization of SPD aka "XFRM rules" |
| 59 | ------------------------------------ | 58 | ------------------------------------ |
| @@ -1409,7 +1408,7 @@ static inline void xfrm_sysctl_fini(struct net *net) | |||
| 1409 | void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto); | 1408 | void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto); |
| 1410 | int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk, | 1409 | int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk, |
| 1411 | int (*func)(struct xfrm_state *, int, void*), void *); | 1410 | int (*func)(struct xfrm_state *, int, void*), void *); |
| 1412 | void xfrm_state_walk_done(struct xfrm_state_walk *walk); | 1411 | void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net); |
| 1413 | struct xfrm_state *xfrm_state_alloc(struct net *net); | 1412 | struct xfrm_state *xfrm_state_alloc(struct net *net); |
| 1414 | struct xfrm_state *xfrm_state_find(const xfrm_address_t *daddr, | 1413 | struct xfrm_state *xfrm_state_find(const xfrm_address_t *daddr, |
| 1415 | const xfrm_address_t *saddr, | 1414 | const xfrm_address_t *saddr, |
| @@ -1436,12 +1435,12 @@ struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, u32 mark, | |||
| 1436 | unsigned short family); | 1435 | unsigned short family); |
| 1437 | #ifdef CONFIG_XFRM_SUB_POLICY | 1436 | #ifdef CONFIG_XFRM_SUB_POLICY |
| 1438 | int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n, | 1437 | int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n, |
| 1439 | unsigned short family); | 1438 | unsigned short family, struct net *net); |
| 1440 | int xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n, | 1439 | int xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n, |
| 1441 | unsigned short family); | 1440 | unsigned short family); |
| 1442 | #else | 1441 | #else |
| 1443 | static inline int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, | 1442 | static inline int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, |
| 1444 | int n, unsigned short family) | 1443 | int n, unsigned short family, struct net *net) |
| 1445 | { | 1444 | { |
| 1446 | return -ENOSYS; | 1445 | return -ENOSYS; |
| 1447 | } | 1446 | } |
| @@ -1553,7 +1552,7 @@ void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type); | |||
| 1553 | int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk, | 1552 | int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk, |
| 1554 | int (*func)(struct xfrm_policy *, int, int, void*), | 1553 | int (*func)(struct xfrm_policy *, int, int, void*), |
| 1555 | void *); | 1554 | void *); |
| 1556 | void xfrm_policy_walk_done(struct xfrm_policy_walk *walk); | 1555 | void xfrm_policy_walk_done(struct xfrm_policy_walk *walk, struct net *net); |
| 1557 | int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl); | 1556 | int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl); |
| 1558 | struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, | 1557 | struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, |
| 1559 | u8 type, int dir, | 1558 | u8 type, int dir, |
| @@ -1576,7 +1575,7 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); | |||
| 1576 | int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, | 1575 | int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, |
| 1577 | const struct xfrm_migrate *m, int num_bundles, | 1576 | const struct xfrm_migrate *m, int num_bundles, |
| 1578 | const struct xfrm_kmaddress *k); | 1577 | const struct xfrm_kmaddress *k); |
| 1579 | struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m); | 1578 | struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net); |
| 1580 | struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x, | 1579 | struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x, |
| 1581 | struct xfrm_migrate *m); | 1580 | struct xfrm_migrate *m); |
| 1582 | int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, | 1581 | int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, |
diff --git a/net/key/af_key.c b/net/key/af_key.c index 3fa811c46913..9a039acf37e8 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
| @@ -1785,7 +1785,9 @@ static int pfkey_dump_sa(struct pfkey_sock *pfk) | |||
| 1785 | 1785 | ||
| 1786 | static void pfkey_dump_sa_done(struct pfkey_sock *pfk) | 1786 | static void pfkey_dump_sa_done(struct pfkey_sock *pfk) |
| 1787 | { | 1787 | { |
| 1788 | xfrm_state_walk_done(&pfk->dump.u.state); | 1788 | struct net *net = sock_net(&pfk->sk); |
| 1789 | |||
| 1790 | xfrm_state_walk_done(&pfk->dump.u.state, net); | ||
| 1789 | } | 1791 | } |
| 1790 | 1792 | ||
| 1791 | static int pfkey_dump(struct sock *sk, struct sk_buff *skb, const struct sadb_msg *hdr, void * const *ext_hdrs) | 1793 | static int pfkey_dump(struct sock *sk, struct sk_buff *skb, const struct sadb_msg *hdr, void * const *ext_hdrs) |
| @@ -1861,7 +1863,7 @@ static u32 gen_reqid(struct net *net) | |||
| 1861 | reqid = IPSEC_MANUAL_REQID_MAX+1; | 1863 | reqid = IPSEC_MANUAL_REQID_MAX+1; |
| 1862 | xfrm_policy_walk_init(&walk, XFRM_POLICY_TYPE_MAIN); | 1864 | xfrm_policy_walk_init(&walk, XFRM_POLICY_TYPE_MAIN); |
| 1863 | rc = xfrm_policy_walk(net, &walk, check_reqid, (void*)&reqid); | 1865 | rc = xfrm_policy_walk(net, &walk, check_reqid, (void*)&reqid); |
| 1864 | xfrm_policy_walk_done(&walk); | 1866 | xfrm_policy_walk_done(&walk, net); |
| 1865 | if (rc != -EEXIST) | 1867 | if (rc != -EEXIST) |
| 1866 | return reqid; | 1868 | return reqid; |
| 1867 | } while (reqid != start); | 1869 | } while (reqid != start); |
| @@ -2660,7 +2662,9 @@ static int pfkey_dump_sp(struct pfkey_sock *pfk) | |||
| 2660 | 2662 | ||
| 2661 | static void pfkey_dump_sp_done(struct pfkey_sock *pfk) | 2663 | static void pfkey_dump_sp_done(struct pfkey_sock *pfk) |
| 2662 | { | 2664 | { |
| 2663 | xfrm_policy_walk_done(&pfk->dump.u.policy); | 2665 | struct net *net = sock_net((struct sock *)pfk); |
| 2666 | |||
| 2667 | xfrm_policy_walk_done(&pfk->dump.u.policy, net); | ||
| 2664 | } | 2668 | } |
| 2665 | 2669 | ||
| 2666 | static int pfkey_spddump(struct sock *sk, struct sk_buff *skb, const struct sadb_msg *hdr, void * const *ext_hdrs) | 2670 | static int pfkey_spddump(struct sock *sk, struct sk_buff *skb, const struct sadb_msg *hdr, void * const *ext_hdrs) |
| @@ -3570,6 +3574,7 @@ static int pfkey_sendmsg(struct kiocb *kiocb, | |||
| 3570 | struct sk_buff *skb = NULL; | 3574 | struct sk_buff *skb = NULL; |
| 3571 | struct sadb_msg *hdr = NULL; | 3575 | struct sadb_msg *hdr = NULL; |
| 3572 | int err; | 3576 | int err; |
| 3577 | struct net *net = sock_net(sk); | ||
| 3573 | 3578 | ||
| 3574 | err = -EOPNOTSUPP; | 3579 | err = -EOPNOTSUPP; |
| 3575 | if (msg->msg_flags & MSG_OOB) | 3580 | if (msg->msg_flags & MSG_OOB) |
| @@ -3592,9 +3597,9 @@ static int pfkey_sendmsg(struct kiocb *kiocb, | |||
| 3592 | if (!hdr) | 3597 | if (!hdr) |
| 3593 | goto out; | 3598 | goto out; |
| 3594 | 3599 | ||
| 3595 | mutex_lock(&xfrm_cfg_mutex); | 3600 | mutex_lock(&net->xfrm.xfrm_cfg_mutex); |
| 3596 | err = pfkey_process(sk, skb, hdr); | 3601 | err = pfkey_process(sk, skb, hdr); |
| 3597 | mutex_unlock(&xfrm_cfg_mutex); | 3602 | mutex_unlock(&net->xfrm.xfrm_cfg_mutex); |
| 3598 | 3603 | ||
| 3599 | out: | 3604 | out: |
| 3600 | if (err && hdr && pfkey_error(hdr, err, sk) == 0) | 3605 | if (err && hdr && pfkey_error(hdr, err, sk) == 0) |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 907fd2fa70bc..73b04d3df44e 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -39,12 +39,7 @@ | |||
| 39 | #define XFRM_QUEUE_TMO_MAX ((unsigned)(60*HZ)) | 39 | #define XFRM_QUEUE_TMO_MAX ((unsigned)(60*HZ)) |
| 40 | #define XFRM_MAX_QUEUE_LEN 100 | 40 | #define XFRM_MAX_QUEUE_LEN 100 |
| 41 | 41 | ||
| 42 | DEFINE_MUTEX(xfrm_cfg_mutex); | ||
| 43 | EXPORT_SYMBOL(xfrm_cfg_mutex); | ||
| 44 | |||
| 45 | static DEFINE_SPINLOCK(xfrm_policy_sk_bundle_lock); | ||
| 46 | static struct dst_entry *xfrm_policy_sk_bundles; | 42 | static struct dst_entry *xfrm_policy_sk_bundles; |
| 47 | static DEFINE_RWLOCK(xfrm_policy_lock); | ||
| 48 | 43 | ||
| 49 | static DEFINE_SPINLOCK(xfrm_policy_afinfo_lock); | 44 | static DEFINE_SPINLOCK(xfrm_policy_afinfo_lock); |
| 50 | static struct xfrm_policy_afinfo __rcu *xfrm_policy_afinfo[NPROTO] | 45 | static struct xfrm_policy_afinfo __rcu *xfrm_policy_afinfo[NPROTO] |
| @@ -438,7 +433,7 @@ static void xfrm_bydst_resize(struct net *net, int dir) | |||
| 438 | if (!ndst) | 433 | if (!ndst) |
| 439 | return; | 434 | return; |
| 440 | 435 | ||
| 441 | write_lock_bh(&xfrm_policy_lock); | 436 | write_lock_bh(&net->xfrm.xfrm_policy_lock); |
| 442 | 437 | ||
| 443 | for (i = hmask; i >= 0; i--) | 438 | for (i = hmask; i >= 0; i--) |
| 444 | xfrm_dst_hash_transfer(odst + i, ndst, nhashmask); | 439 | xfrm_dst_hash_transfer(odst + i, ndst, nhashmask); |
| @@ -446,7 +441,7 @@ static void xfrm_bydst_resize(struct net *net, int dir) | |||
| 446 | net->xfrm.policy_bydst[dir].table = ndst; | 441 | net->xfrm.policy_bydst[dir].table = ndst; |
| 447 | net->xfrm.policy_bydst[dir].hmask = nhashmask; | 442 | net->xfrm.policy_bydst[dir].hmask = nhashmask; |
| 448 | 443 | ||
| 449 | write_unlock_bh(&xfrm_policy_lock); | 444 | write_unlock_bh(&net->xfrm.xfrm_policy_lock); |
| 450 | 445 | ||
| 451 | xfrm_hash_free(odst, (hmask + 1) * sizeof(struct hlist_head)); | 446 | xfrm_hash_free(odst, (hmask + 1) * sizeof(struct hlist_head)); |
| 452 | } | 447 | } |
| @@ -463,7 +458,7 @@ static void xfrm_byidx_resize(struct net *net, int total) | |||
| 463 | if (!nidx) | 458 | if (!nidx) |
| 464 | return; | 459 | return; |
| 465 | 460 | ||
