Commit 611f1929 authored by Herbert Xu's avatar Herbert Xu Committed by Stephen Hemminger

[IPSEC]: Use xfrm_rcv for xfrm tunnel packets.

parent 97ddbec4
...@@ -279,6 +279,7 @@ static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x) ...@@ -279,6 +279,7 @@ static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x)
t->props.family = AF_INET; t->props.family = AF_INET;
t->props.mode = 1; t->props.mode = 1;
t->props.saddr.a4 = x->props.saddr.a4; t->props.saddr.a4 = x->props.saddr.a4;
t->props.flags = x->props.flags;
t->type = xfrm_get_type(IPPROTO_IPIP, t->props.family); t->type = xfrm_get_type(IPPROTO_IPIP, t->props.family);
if (t->type == NULL) if (t->type == NULL)
......
...@@ -27,6 +27,20 @@ static inline void ipip_ecn_decapsulate(struct iphdr *outer_iph, struct sk_buff ...@@ -27,6 +27,20 @@ static inline void ipip_ecn_decapsulate(struct iphdr *outer_iph, struct sk_buff
IP_ECN_set_ce(inner_iph); IP_ECN_set_ce(inner_iph);
} }
static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq)
{
switch (nexthdr) {
case IPPROTO_IPIP:
if (!pskb_may_pull(skb, sizeof(struct iphdr)))
return -EINVAL;
*spi = skb->nh.iph->saddr;
*seq = 0;
return 0;
}
return xfrm_parse_spi(skb, nexthdr, spi, seq);
}
int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
{ {
int err; int err;
...@@ -36,7 +50,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) ...@@ -36,7 +50,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
int xfrm_nr = 0; int xfrm_nr = 0;
int decaps = 0; int decaps = 0;
if ((err = xfrm_parse_spi(skb, skb->nh.iph->protocol, &spi, &seq)) != 0) if ((err = xfrm4_parse_spi(skb, skb->nh.iph->protocol, &spi, &seq)) != 0)
goto drop; goto drop;
do { do {
......
...@@ -83,31 +83,8 @@ static int ipip_output(struct sk_buff *skb) ...@@ -83,31 +83,8 @@ static int ipip_output(struct sk_buff *skb)
return err; return err;
} }
static inline void ipip_ecn_decapsulate(struct iphdr *outer_iph, struct sk_buff *skb)
{
struct iphdr *inner_iph = skb->nh.iph;
if (INET_ECN_is_ce(outer_iph->tos) &&
INET_ECN_is_not_ce(inner_iph->tos))
IP_ECN_set_ce(inner_iph);
}
static int ipip_xfrm_rcv(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) static int ipip_xfrm_rcv(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
{ {
struct iphdr *outer_iph = skb->nh.iph;
if (!pskb_may_pull(skb, sizeof(struct iphdr)))
return -EINVAL;
skb->mac.raw = skb->nh.raw;
skb->nh.raw = skb->data;
memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
dst_release(skb->dst);
skb->dst = NULL;
skb->protocol = htons(ETH_P_IP);
skb->pkt_type = PACKET_HOST;
ipip_ecn_decapsulate(outer_iph, skb);
netif_rx(skb);
return 0; return 0;
} }
...@@ -149,46 +126,12 @@ int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler) ...@@ -149,46 +126,12 @@ int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler)
static int ipip_rcv(struct sk_buff *skb) static int ipip_rcv(struct sk_buff *skb)
{ {
struct xfrm_tunnel *handler = ipip_handler; struct xfrm_tunnel *handler = ipip_handler;
struct xfrm_state *x = NULL;
int err;
/* Tunnel devices take precedence. */ /* Tunnel devices take precedence. */
if (handler) { if (handler && handler->handler(skb) == 0)
err = handler->handler(skb); return 0;
if (!err)
goto out;
}
x = xfrm_state_lookup((xfrm_address_t *)&skb->nh.iph->daddr,
skb->nh.iph->saddr,
IPPROTO_IPIP, AF_INET);
if (!x)
goto drop;
spin_lock(&x->lock);
if (unlikely(x->km.state != XFRM_STATE_VALID))
goto drop_unlock;
err = ipip_xfrm_rcv(x, NULL, skb);
if (err)
goto drop_unlock;
x->curlft.bytes += skb->len;
x->curlft.packets++;
spin_unlock(&x->lock);
xfrm_state_put(x);
out:
return err;
drop_unlock: return xfrm4_rcv_encap(skb, 0);
spin_unlock(&x->lock);
xfrm_state_put(x);
drop:
err = NET_RX_DROP;
kfree_skb(skb);
goto out;
} }
static void ipip_err(struct sk_buff *skb, u32 info) static void ipip_err(struct sk_buff *skb, u32 info)
......
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