summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2004-08-18 00:51:44 -0700
committerDavid S. Miller <davem@kernel.bkbits.net>2004-08-18 00:51:44 -0700
commitaf597aa67c3e0e785fcfbcc3bddfe6643b7e49cb (patch)
tree94fb6708908a7c695ca97bf55afd92080053b06d
parent1126996a1f42e82a334339ff099a1580888d3a9a (diff)
[IPSEC]: Call xfrm6_rcv in xfrm6_tunnel_rcv
This patch reuses the code in xfrm6_input.c for receiving xfrm6_tunnel packets. This removes duplicate code as well as fixing the bugs unique to xfrm6_tunnel_input. For example, it didn't move the MAC header down. Nor did it do anything with ECN. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@redhat.com>
-rw-r--r--include/net/xfrm.h1
-rw-r--r--net/ipv6/xfrm6_input.c15
-rw-r--r--net/ipv6/xfrm6_tunnel.c51
3 files changed, 16 insertions, 51 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index fdf3409b9209..5c51339eec13 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -780,6 +780,7 @@ extern int xfrm4_rcv(struct sk_buff *skb);
extern int xfrm4_output(struct sk_buff **pskb);
extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler);
extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler);
+extern int xfrm6_rcv_spi(struct sk_buff **pskb, unsigned int *nhoffp, u32 spi);
extern int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp);
extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler);
extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler);
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 0791594f8878..92e74233fcdb 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -9,6 +9,7 @@
* IPv6 support
*/
+#include <linux/module.h>
#include <linux/string.h>
#include <net/inet_ecn.h>
#include <net/ip.h>
@@ -25,11 +26,11 @@ static inline void ipip6_ecn_decapsulate(struct sk_buff *skb)
IP6_ECN_set_ce(inner_iph);
}
-int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
+int xfrm6_rcv_spi(struct sk_buff **pskb, unsigned int *nhoffp, u32 spi)
{
struct sk_buff *skb = *pskb;
int err;
- u32 spi, seq;
+ u32 seq;
struct sec_decap_state xfrm_vec[XFRM_MAX_DEPTH];
struct xfrm_state *x;
int xfrm_nr = 0;
@@ -40,7 +41,8 @@ int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
nhoff = *nhoffp;
nexthdr = skb->nh.raw[nhoff];
- if ((err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
+ seq = 0;
+ if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
goto drop;
do {
@@ -137,3 +139,10 @@ drop:
kfree_skb(skb);
return -1;
}
+
+EXPORT_SYMBOL(xfrm6_rcv_spi);
+
+int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
+{
+ return xfrm6_rcv_spi(pskb, nhoffp, 0);
+}
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index fb5b34a0d4c4..a9736d2ea721 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -356,17 +356,6 @@ static int xfrm6_tunnel_output(struct sk_buff **pskb)
static int xfrm6_tunnel_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
{
- if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
- return -EINVAL;
-
- skb->mac.raw = skb->nh.raw;
- skb->nh.raw = skb->data;
- dst_release(skb->dst);
- skb->dst = NULL;
- skb->protocol = htons(ETH_P_IPV6);
- skb->pkt_type = PACKET_HOST;
- netif_rx(skb);
-
return 0;
}
@@ -413,49 +402,15 @@ static int xfrm6_tunnel_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
{
struct sk_buff *skb = *pskb;
struct xfrm6_tunnel *handler = xfrm6_tunnel_handler;
- struct xfrm_state *x = NULL;
struct ipv6hdr *iph = skb->nh.ipv6h;
- int err = 0;
u32 spi;
/* device-like_ip6ip6_handler() */
- if (handler) {
- err = handler->handler(pskb, nhoffp);
- if (!err)
- goto out;
- }
+ if (handler && handler->handler(pskb, nhoffp) == 0)
+ return 0;
spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr);
- x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr,
- spi,
- IPPROTO_IPV6, AF_INET6);
-
- if (!x)
- goto drop;
-
- spin_lock(&x->lock);
-
- if (unlikely(x->km.state != XFRM_STATE_VALID))
- goto drop_unlock;
-
- err = xfrm6_tunnel_input(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 0;
-
-drop_unlock:
- spin_unlock(&x->lock);
- xfrm_state_put(x);
-drop:
- kfree_skb(skb);
- return -1;
+ return xfrm6_rcv_spi(pskb, nhoffp, spi);
}
static void xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,