Re: [IPSEC] Use xfrm_rcv for xfrm tunnel packets

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Jul 30, 2003 at 05:31:43PM -0700, David S. Miller wrote:
> On Tue, 29 Jul 2003 21:33:24 +1000
> Herbert Xu <herbert@gondor.apana.org.au> wrote:
> 
> > This patch makes the xfrm_tunnel code use the same receive functions
> > as other IPSEC tunnels.
> 
> Need something similar on the ipv6 side if we're going
> to seriously consider this.

I agree that we need to handle IPCOMP for IPv6 in the same way as
we do now for IPv4.  However, I think that would be a different
patch.

In fact, I think that we need to preserve the guarantee that no
two addresses share the same XFRM tunnel for IPv6.  To do that,
we will need to extend the SPI key in the SADB to at least 128
bits.

> So I did not want this knowledge inside of the generic xfrm_input.c
> file as a result, and that's what you're doing here :(

That makes sense.  How about this patch.

Cheers,
-- 
Debian GNU/Linux 3.0 is out! ( http://www.debian.org/ )
Email:  Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Index: kernel-source-2.5/net/ipv4/ipcomp.c
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/ipv4/ipcomp.c,v
retrieving revision 1.3
diff -u -r1.3 ipcomp.c
--- kernel-source-2.5/net/ipv4/ipcomp.c	29 Jul 2003 11:11:34 -0000	1.3
+++ kernel-source-2.5/net/ipv4/ipcomp.c	31 Jul 2003 09:14:28 -0000
@@ -280,6 +280,7 @@
 	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)
Index: kernel-source-2.5/net/ipv4/xfrm4_input.c
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/ipv4/xfrm4_input.c,v
retrieving revision 1.4
diff -u -r1.4 xfrm4_input.c
--- kernel-source-2.5/net/ipv4/xfrm4_input.c	28 Jul 2003 11:31:30 -0000	1.4
+++ kernel-source-2.5/net/ipv4/xfrm4_input.c	31 Jul 2003 09:23:01 -0000
@@ -27,6 +27,20 @@
 		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 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 {
@@ -90,7 +104,7 @@
 			break;
 		}
 
-		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;
 	} while (!err);
 
Index: kernel-source-2.5/net/ipv4/xfrm4_tunnel.c
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/ipv4/xfrm4_tunnel.c,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 xfrm4_tunnel.c
--- kernel-source-2.5/net/ipv4/xfrm4_tunnel.c	17 Jun 2003 04:19:40 -0000	1.1.1.3
+++ kernel-source-2.5/net/ipv4/xfrm4_tunnel.c	31 Jul 2003 09:14:28 -0000
@@ -83,31 +83,8 @@
 	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 @@
 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;
-	}
+	if (handler && handler->handler(skb) == 0)
+		return 0;
 
-	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:
-	spin_unlock(&x->lock);
-	xfrm_state_put(x);
-drop:
-	err = NET_RX_DROP;
-	kfree_skb(skb);
-	goto out;
+	return xfrm4_rcv(skb);
 }
 
 static void ipip_err(struct sk_buff *skb, u32 info)

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux