forked from luck/tmp_suning_uos_patched
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next
Steffen Klassert says: ==================== 1) Don't use a wildcard SA if a more precise one is in acquire state, from Fan Du. 2) Simplify the SA lookup when using wildcard source. We need to check only the destination in this case, from Fan Du. 3) Add a receive path hook for IPsec virtual tunnel interfaces to xfrm6_mode_tunnel. 4) Add support for IPsec virtual tunnel interfaces to ipv6. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
9aaf0435b4
@ -1508,6 +1508,8 @@ int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
|
||||
void xfrm4_local_error(struct sk_buff *skb, u32 mtu);
|
||||
int xfrm4_mode_tunnel_input_register(struct xfrm_tunnel_notifier *handler);
|
||||
int xfrm4_mode_tunnel_input_deregister(struct xfrm_tunnel_notifier *handler);
|
||||
int xfrm6_mode_tunnel_input_register(struct xfrm_tunnel_notifier *handler);
|
||||
int xfrm6_mode_tunnel_input_deregister(struct xfrm_tunnel_notifier *handler);
|
||||
int xfrm6_extract_header(struct sk_buff *skb);
|
||||
int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
|
||||
int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi);
|
||||
|
@ -153,6 +153,17 @@ config INET6_XFRM_MODE_ROUTEOPTIMIZATION
|
||||
---help---
|
||||
Support for MIPv6 route optimization mode.
|
||||
|
||||
config IPV6_VTI
|
||||
tristate "Virtual (secure) IPv6: tunneling"
|
||||
select IPV6_TUNNEL
|
||||
depends on INET6_XFRM_MODE_TUNNEL
|
||||
---help---
|
||||
Tunneling means encapsulating data of one protocol type within
|
||||
another protocol and sending it over a channel that understands the
|
||||
encapsulating protocol. This can be used with xfrm mode tunnel to give
|
||||
the notion of a secure tunnel for IPSEC and then use routing protocol
|
||||
on top.
|
||||
|
||||
config IPV6_SIT
|
||||
tristate "IPv6: IPv6-in-IPv4 tunnel (SIT driver)"
|
||||
select INET_TUNNEL
|
||||
|
@ -36,6 +36,7 @@ obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o
|
||||
obj-$(CONFIG_IPV6_MIP6) += mip6.o
|
||||
obj-$(CONFIG_NETFILTER) += netfilter/
|
||||
|
||||
obj-$(CONFIG_IPV6_VTI) += ip6_vti.o
|
||||
obj-$(CONFIG_IPV6_SIT) += sit.o
|
||||
obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o
|
||||
obj-$(CONFIG_IPV6_GRE) += ip6_gre.o
|
||||
|
1056
net/ipv6/ip6_vti.c
Normal file
1056
net/ipv6/ip6_vti.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -18,6 +18,65 @@
|
||||
#include <net/ipv6.h>
|
||||
#include <net/xfrm.h>
|
||||
|
||||
/* Informational hook. The decap is still done here. */
|
||||
static struct xfrm_tunnel_notifier __rcu *rcv_notify_handlers __read_mostly;
|
||||
static DEFINE_MUTEX(xfrm6_mode_tunnel_input_mutex);
|
||||
|
||||
int xfrm6_mode_tunnel_input_register(struct xfrm_tunnel_notifier *handler)
|
||||
{
|
||||
struct xfrm_tunnel_notifier __rcu **pprev;
|
||||
struct xfrm_tunnel_notifier *t;
|
||||
int ret = -EEXIST;
|
||||
int priority = handler->priority;
|
||||
|
||||
mutex_lock(&xfrm6_mode_tunnel_input_mutex);
|
||||
|
||||
for (pprev = &rcv_notify_handlers;
|
||||
(t = rcu_dereference_protected(*pprev,
|
||||
lockdep_is_held(&xfrm6_mode_tunnel_input_mutex))) != NULL;
|
||||
pprev = &t->next) {
|
||||
if (t->priority > priority)
|
||||
break;
|
||||
if (t->priority == priority)
|
||||
goto err;
|
||||
|
||||
}
|
||||
|
||||
handler->next = *pprev;
|
||||
rcu_assign_pointer(*pprev, handler);
|
||||
|
||||
ret = 0;
|
||||
|
||||
err:
|
||||
mutex_unlock(&xfrm6_mode_tunnel_input_mutex);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xfrm6_mode_tunnel_input_register);
|
||||
|
||||
int xfrm6_mode_tunnel_input_deregister(struct xfrm_tunnel_notifier *handler)
|
||||
{
|
||||
struct xfrm_tunnel_notifier __rcu **pprev;
|
||||
struct xfrm_tunnel_notifier *t;
|
||||
int ret = -ENOENT;
|
||||
|
||||
mutex_lock(&xfrm6_mode_tunnel_input_mutex);
|
||||
for (pprev = &rcv_notify_handlers;
|
||||
(t = rcu_dereference_protected(*pprev,
|
||||
lockdep_is_held(&xfrm6_mode_tunnel_input_mutex))) != NULL;
|
||||
pprev = &t->next) {
|
||||
if (t == handler) {
|
||||
*pprev = handler->next;
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&xfrm6_mode_tunnel_input_mutex);
|
||||
synchronize_net();
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xfrm6_mode_tunnel_input_deregister);
|
||||
|
||||
static inline void ipip6_ecn_decapsulate(struct sk_buff *skb)
|
||||
{
|
||||
const struct ipv6hdr *outer_iph = ipv6_hdr(skb);
|
||||
@ -63,8 +122,15 @@ static int xfrm6_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define for_each_input_rcu(head, handler) \
|
||||
for (handler = rcu_dereference(head); \
|
||||
handler != NULL; \
|
||||
handler = rcu_dereference(handler->next))
|
||||
|
||||
|
||||
static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
|
||||
{
|
||||
struct xfrm_tunnel_notifier *handler;
|
||||
int err = -EINVAL;
|
||||
|
||||
if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPV6)
|
||||
@ -72,6 +138,9 @@ static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
|
||||
if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
|
||||
goto out;
|
||||
|
||||
for_each_input_rcu(rcv_notify_handlers, handler)
|
||||
handler->handler(skb);
|
||||
|
||||
err = skb_unclone(skb, GFP_ATOMIC);
|
||||
if (err)
|
||||
goto out;
|
||||
|
@ -815,7 +815,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
|
||||
xfrm_state_look_at(pol, x, fl, encap_family,
|
||||
&best, &acquire_in_progress, &error);
|
||||
}
|
||||
if (best)
|
||||
if (best || acquire_in_progress)
|
||||
goto found;
|
||||
|
||||
h_wildcard = xfrm_dst_hash(net, daddr, &saddr_wildcard, tmpl->reqid, encap_family);
|
||||
@ -824,7 +824,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
|
||||
x->props.reqid == tmpl->reqid &&
|
||||
(mark & x->mark.m) == x->mark.v &&
|
||||
!(x->props.flags & XFRM_STATE_WILDRECV) &&
|
||||
xfrm_state_addr_check(x, daddr, saddr, encap_family) &&
|
||||
xfrm_addr_equal(&x->id.daddr, daddr, encap_family) &&
|
||||
tmpl->mode == x->props.mode &&
|
||||
tmpl->id.proto == x->id.proto &&
|
||||
(tmpl->id.spi == x->id.spi || !tmpl->id.spi))
|
||||
|
Loading…
Reference in New Issue
Block a user