[IPSEC] Use xfrm_rcv for xfrm tunnel packets

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

 



Hi:

This is part of my previous proposal on strengthening policy checks.

This patch makes the xfrm_tunnel code use the same receive functions
as other IPSEC tunnels.  As a result, this inserts the tunnel state
into the security path.  This should be OK as our current policy check
allows unspecified SAs.  It also means that the IPCOMP SA selector
is checked even when the packet is not compressed.  Of course, if
the user creates multiple IPCOMP SAs between the same pair of hosts
with differing selectors, then they deserve to lose.

One side effect is that it makes the NOECN flag useful for IPCOMP SAs
assuming that the user makes sure that all IPCOMP SAs sharing the same
tunnel state agrees on the flag.

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	29 Jul 2003 11:21:08 -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_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	29 Jul 2003 11:13:32 -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: kernel-source-2.5/net/xfrm/xfrm_input.c
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/xfrm/xfrm_input.c,v
retrieving revision 1.2
diff -u -r1.2 xfrm_input.c
--- kernel-source-2.5/net/xfrm/xfrm_input.c	28 Jul 2003 11:31:30 -0000	1.2
+++ kernel-source-2.5/net/xfrm/xfrm_input.c	29 Jul 2003 11:13:32 -0000
@@ -62,6 +62,12 @@
 		*spi = ntohl(ntohs(*(u16*)(skb->h.raw + 2)));
 		*seq = 0;
 		return 0;
+	case IPPROTO_IPIP:
+		if (!pskb_may_pull(skb, sizeof(struct iphdr)))
+			return -EINVAL;
+		*spi = skb->nh.iph->saddr;
+		*seq = 0;
+		return 0;
 	default:
 		return 1;
 	}

[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