mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-30 21:44:27 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			142 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			142 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| packaging/utils/nattpatch 2.4
 | |
| --- a/include/net/sock.h
 | |
| +++ b/include/net/sock.h
 | |
| @@ -488,7 +488,13 @@ struct tcp_opt {
 | |
|  	} 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 @@ struct sock {
 | |
|  #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;
 | |
|  
 | |
| --- a/net/Config.in
 | |
| +++ b/net/Config.in
 | |
| @@ -104,4 +104,6 @@ comment 'Network testing'
 | |
|  dep_tristate 'Packet Generator (USE WITH CAUTION)' CONFIG_NET_PKTGEN $CONFIG_PROC_FS
 | |
|  endmenu
 | |
|  
 | |
| +bool 'IPSEC NAT-Traversal' CONFIG_IPSEC_NAT_TRAVERSAL
 | |
| +
 | |
|  endmenu
 | |
| --- a/net/ipv4/udp.c
 | |
| +++ b/net/ipv4/udp.c
 | |
| @@ -860,6 +860,9 @@ static void udp_close(struct sock *sk, l
 | |
|  
 | |
|  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.
 | |
|  	 */
 | |
| @@ -877,6 +880,40 @@ static int udp_queue_rcv_skb(struct sock
 | |
|  	}
 | |
|  #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);
 | |
| @@ -1100,13 +1137,49 @@ out:
 | |
|  	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,
 |