diff options
Diffstat (limited to 'package/linux/kernel-patches/311-ipsec-nat-traversal')
| -rw-r--r-- | package/linux/kernel-patches/311-ipsec-nat-traversal | 140 | 
1 files changed, 140 insertions, 0 deletions
diff --git a/package/linux/kernel-patches/311-ipsec-nat-traversal b/package/linux/kernel-patches/311-ipsec-nat-traversal new file mode 100644 index 000000000..fc4c29d27 --- /dev/null +++ b/package/linux/kernel-patches/311-ipsec-nat-traversal @@ -0,0 +1,140 @@ +packaging/utils/nattpatch 2.4 +--- linux/include/net/sock.h	2002/02/06 15:25:10	1.1 ++++ linux/include/net/sock.h	2002/05/22 12:14:56 +@@ -488,7 +488,13 @@ + 	} bictcp; + }; +  +- 	 ++#if 1 ++#define UDP_OPT_IN_SOCK 1 ++struct udp_opt { ++	__u32 esp_in_udp; ++}; ++#endif ++ + /* +  * This structure really needs to be cleaned up. +  * Most of it is for TCP, and not used by any of +@@ -655,6 +661,9 @@ + #if defined(CONFIG_SPX) || defined (CONFIG_SPX_MODULE) + 		struct spx_opt		af_spx; + #endif /* CONFIG_SPX */ ++#if 1 ++		struct udp_opt          af_udp; ++#endif +  + 	} tp_pinfo; +  +--- linux/net/Config.in.orig	Fri Feb  9 14:34:13 2001 ++++ linux/net/Config.in	Thu Feb 22 19:40:08 2001 +@@ -88,3 +88,5 @@ + endmenu +  ++bool 'IPSEC NAT-Traversal' CONFIG_IPSEC_NAT_TRAVERSAL ++ + endmenu +--- linux/net/ipv4/udp.c.1	Wed Jan 28 15:57:05 2004 ++++ linux/net/ipv4/udp.c	Wed Jan 28 15:58:56 2004 +@@ -787,6 +787,9 @@ +  + static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) + { ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++	struct udp_opt *tp =  &(sk->tp_pinfo.af_udp); ++#endif + 	/* + 	 *	Charge it to the socket, dropping if the queue is full. + 	 */ +@@ -804,6 +807,40 @@ + 	} + #endif +  ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++	if (tp->esp_in_udp) { ++		/* ++		 * Set skb->sk and xmit packet to ipsec_rcv. ++		 * ++		 * If ret != 0, ipsec_rcv refused the packet (not ESPinUDP), ++		 * restore skb->sk and fall back to sock_queue_rcv_skb ++		 */ ++		struct inet_protocol *esp = NULL; ++ ++#if defined(CONFIG_KLIPS) && !defined(CONFIG_KLIPS_MODULE) ++               /* optomize only when we know it is statically linked */ ++		extern struct inet_protocol esp_protocol; ++		esp = &esp_protocol; ++#else ++		for (esp = (struct inet_protocol *)inet_protos[IPPROTO_ESP & (MAX_INET_PROTOS - 1)]; ++			(esp) && (esp->protocol != IPPROTO_ESP); ++			esp = esp->next); ++#endif ++ ++		if (esp && esp->handler) { ++			struct sock *sav_sk = skb->sk; ++			skb->sk = sk; ++			if (esp->handler(skb) == 0) { ++				skb->sk = sav_sk; ++				/*not sure we might count ESPinUDP as UDP...*/ ++				UDP_INC_STATS_BH(UdpInDatagrams); ++				return 0; ++			} ++			skb->sk = sav_sk; ++		} ++	} ++#endif ++ + 	if (sock_queue_rcv_skb(sk,skb)<0) { + 		UDP_INC_STATS_BH(UdpInErrors); + 		IP_INC_STATS_BH(IpInDiscards); +@@ -1027,13 +1064,49 @@ + 	return len; + } +  ++static int udp_setsockopt(struct sock *sk, int level, int optname, ++	char *optval, int optlen) ++{ ++	struct udp_opt *tp = &(sk->tp_pinfo.af_udp); ++	int val; ++	int err = 0; ++ ++	if (level != SOL_UDP) ++		return ip_setsockopt(sk, level, optname, optval, optlen); ++ ++	if(optlen<sizeof(int)) ++		return -EINVAL; ++ ++	if (get_user(val, (int *)optval)) ++		return -EFAULT; ++	 ++	lock_sock(sk); ++ ++	switch(optname) { ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++#ifndef UDP_ESPINUDP ++#define UDP_ESPINUDP 100 ++#endif ++		case UDP_ESPINUDP: ++			tp->esp_in_udp = val; ++			break; ++#endif ++		default: ++			err = -ENOPROTOOPT; ++			break; ++	} ++ ++	release_sock(sk); ++	return err; ++} ++ + struct proto udp_prot = { +  	name:		"UDP", + 	close:		udp_close, + 	connect:	udp_connect, + 	disconnect:	udp_disconnect, + 	ioctl:		udp_ioctl, +-	setsockopt:	ip_setsockopt, ++	setsockopt:	udp_setsockopt, + 	getsockopt:	ip_getsockopt, + 	sendmsg:	udp_sendmsg, + 	recvmsg:	udp_recvmsg,  | 
