aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-03-18 14:09:07 -0400
committerDavid S. Miller <davem@davemloft.net>2014-03-18 14:09:07 -0400
commit995dca4ce9dddf48597bd3e0427447acd4509f1d (patch)
treeea74e64d0cf2b957ff4dc22e53f4140eabfb0495 /net/xfrm
parentd70e941bff5f223017ba7001b8eb0423a636c070 (diff)
parent61220ab349485d911083d0b7990ccd3db6c63297 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next
Steffen Klassert says: ==================== One patch to rename a newly introduced struct. The rest is the rework of the IPsec virtual tunnel interface for ipv6 to support inter address family tunneling and namespace crossing. 1) Rename the newly introduced struct xfrm_filter to avoid a conflict with iproute2. From Nicolas Dichtel. 2) Introduce xfrm_input_afinfo to access the address family dependent tunnel callback functions properly. 3) Add and use a IPsec protocol multiplexer for ipv6. 4) Remove dst_entry caching. vti can lookup multiple different dst entries, dependent of the configured xfrm states. Therefore it does not make to cache a dst_entry. 5) Remove caching of flow informations. vti6 does not use the the tunnel endpoint addresses to do route and xfrm lookups. 6) Update the vti6 to use its own receive hook. 7) Remove the now unused xfrm_tunnel_notifier. This was used from vti and is replaced by the IPsec protocol multiplexer hooks. 8) Support inter address family tunneling for vti6. 9) Check if the tunnel endpoints of the xfrm state and the vti interface are matching and return an error otherwise. 10) Enable namespace crossing for vti devices. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm')
-rw-r--r--net/xfrm/xfrm_input.c75
-rw-r--r--net/xfrm/xfrm_state.c4
-rw-r--r--net/xfrm/xfrm_user.c8
3 files changed, 81 insertions, 6 deletions
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 4218164f4f5e..85d1d4764612 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -16,6 +16,81 @@
16 16
17static struct kmem_cache *secpath_cachep __read_mostly; 17static struct kmem_cache *secpath_cachep __read_mostly;
18 18
19static DEFINE_SPINLOCK(xfrm_input_afinfo_lock);
20static struct xfrm_input_afinfo __rcu *xfrm_input_afinfo[NPROTO];
21
22int xfrm_input_register_afinfo(struct xfrm_input_afinfo *afinfo)
23{
24 int err = 0;
25
26 if (unlikely(afinfo == NULL))
27 return -EINVAL;
28 if (unlikely(afinfo->family >= NPROTO))
29 return -EAFNOSUPPORT;
30 spin_lock_bh(&xfrm_input_afinfo_lock);
31 if (unlikely(xfrm_input_afinfo[afinfo->family] != NULL))
32 err = -ENOBUFS;
33 else
34 rcu_assign_pointer(xfrm_input_afinfo[afinfo->family], afinfo);
35 spin_unlock_bh(&xfrm_input_afinfo_lock);
36 return err;
37}
38EXPORT_SYMBOL(xfrm_input_register_afinfo);
39
40int xfrm_input_unregister_afinfo(struct xfrm_input_afinfo *afinfo)
41{
42 int err = 0;
43
44 if (unlikely(afinfo == NULL))
45 return -EINVAL;
46 if (unlikely(afinfo->family >= NPROTO))
47 return -EAFNOSUPPORT;
48 spin_lock_bh(&xfrm_input_afinfo_lock);
49 if (likely(xfrm_input_afinfo[afinfo->family] != NULL)) {
50 if (unlikely(xfrm_input_afinfo[afinfo->family] != afinfo))
51 err = -EINVAL;
52 else
53 RCU_INIT_POINTER(xfrm_input_afinfo[afinfo->family], NULL);
54 }
55 spin_unlock_bh(&xfrm_input_afinfo_lock);
56 synchronize_rcu();
57 return err;
58}
59EXPORT_SYMBOL(xfrm_input_unregister_afinfo);
60
61static struct xfrm_input_afinfo *xfrm_input_get_afinfo(unsigned int family)
62{
63 struct xfrm_input_afinfo *afinfo;
64
65 if (unlikely(family >= NPROTO))
66 return NULL;
67 rcu_read_lock();
68 afinfo = rcu_dereference(xfrm_input_afinfo[family]);
69 if (unlikely(!afinfo))
70 rcu_read_unlock();
71 return afinfo;
72}
73
74static void xfrm_input_put_afinfo(struct xfrm_input_afinfo *afinfo)
75{
76 rcu_read_unlock();
77}
78
79static int xfrm_rcv_cb(struct sk_buff *skb, unsigned int family, u8 protocol,
80 int err)
81{
82 int ret;
83 struct xfrm_input_afinfo *afinfo = xfrm_input_get_afinfo(family);
84
85 if (!afinfo)
86 return -EAFNOSUPPORT;
87
88 ret = afinfo->callback(skb, protocol, err);
89 xfrm_input_put_afinfo(afinfo);
90
91 return ret;
92}
93
19void __secpath_destroy(struct sec_path *sp) 94void __secpath_destroy(struct sec_path *sp)
20{ 95{
21 int i; 96 int i;
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 06970fee9155..8e9c781a6bba 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1609,7 +1609,7 @@ unlock:
1609EXPORT_SYMBOL(xfrm_alloc_spi); 1609EXPORT_SYMBOL(xfrm_alloc_spi);
1610 1610
1611static bool __xfrm_state_filter_match(struct xfrm_state *x, 1611static bool __xfrm_state_filter_match(struct xfrm_state *x,
1612 struct xfrm_filter *filter) 1612 struct xfrm_address_filter *filter)
1613{ 1613{
1614 if (filter) { 1614 if (filter) {
1615 if ((filter->family == AF_INET || 1615 if ((filter->family == AF_INET ||
@@ -1668,7 +1668,7 @@ out:
1668EXPORT_SYMBOL(xfrm_state_walk); 1668EXPORT_SYMBOL(xfrm_state_walk);
1669 1669
1670void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto, 1670void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto,
1671 struct xfrm_filter *filter) 1671 struct xfrm_address_filter *filter)
1672{ 1672{
1673 INIT_LIST_HEAD(&walk->all); 1673 INIT_LIST_HEAD(&walk->all);
1674 walk->proto = proto; 1674 walk->proto = proto;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 195dbe230b98..cdd9e9c7ff0e 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -899,7 +899,7 @@ static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb)
899 899
900 if (!cb->args[0]) { 900 if (!cb->args[0]) {
901 struct nlattr *attrs[XFRMA_MAX+1]; 901 struct nlattr *attrs[XFRMA_MAX+1];
902 struct xfrm_filter *filter = NULL; 902 struct xfrm_address_filter *filter = NULL;
903 u8 proto = 0; 903 u8 proto = 0;
904 int err; 904 int err;
905 905
@@ -910,12 +910,12 @@ static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb)
910 if (err < 0) 910 if (err < 0)
911 return err; 911 return err;
912 912
913 if (attrs[XFRMA_FILTER]) { 913 if (attrs[XFRMA_ADDRESS_FILTER]) {
914 filter = kmalloc(sizeof(*filter), GFP_KERNEL); 914 filter = kmalloc(sizeof(*filter), GFP_KERNEL);
915 if (filter == NULL) 915 if (filter == NULL)
916 return -ENOMEM; 916 return -ENOMEM;
917 917
918 memcpy(filter, nla_data(attrs[XFRMA_FILTER]), 918 memcpy(filter, nla_data(attrs[XFRMA_ADDRESS_FILTER]),
919 sizeof(*filter)); 919 sizeof(*filter));
920 } 920 }
921 921
@@ -2329,7 +2329,7 @@ static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {
2329 [XFRMA_REPLAY_ESN_VAL] = { .len = sizeof(struct xfrm_replay_state_esn) }, 2329 [XFRMA_REPLAY_ESN_VAL] = { .len = sizeof(struct xfrm_replay_state_esn) },
2330 [XFRMA_SA_EXTRA_FLAGS] = { .type = NLA_U32 }, 2330 [XFRMA_SA_EXTRA_FLAGS] = { .type = NLA_U32 },
2331 [XFRMA_PROTO] = { .type = NLA_U8 }, 2331 [XFRMA_PROTO] = { .type = NLA_U8 },
2332 [XFRMA_FILTER] = { .len = sizeof(struct xfrm_filter) }, 2332 [XFRMA_ADDRESS_FILTER] = { .len = sizeof(struct xfrm_address_filter) },
2333}; 2333};
2334 2334
2335static const struct xfrm_link { 2335static const struct xfrm_link {