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)
t->props.family = AF_INET;
t->props.mode = 1;
t->props.saddr.a4 = x->props.saddr.a4;
t->props.flags = x->props.flags;
t->type = xfrm_get_type(IPPROTO_IPIP, t->props.family);
if (t->type == NULL)
......
......@@ -27,6 +27,20 @@ static inline void ipip_ecn_decapsulate(struct iphdr *outer_iph, struct sk_buff
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 err;
......@@ -36,7 +50,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
int xfrm_nr = 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;
do {
......
......@@ -83,31 +83,8 @@ static int ipip_output(struct sk_buff *skb)
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)
{
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;
}
......@@ -149,46 +126,12 @@ int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler)
static int ipip_rcv(struct sk_buff *skb)
{
struct xfrm_tunnel *handler = ipip_handler;
struct xfrm_state *x = NULL;
int err;
/* Tunnel devices take precedence. */
if (handler) {
err = handler->handler(skb);
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;
if (handler && handler->handler(skb) == 0)
return 0;
drop_unlock:
spin_unlock(&x->lock);
xfrm_state_put(x);
drop:
err = NET_RX_DROP;
kfree_skb(skb);
goto out;
return xfrm4_rcv_encap(skb, 0);
}
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