757df15e21b77142300e3f6bddaa4ea967b3b072
[openwrt/staging/yousong.git] / target / linux / generic-2.4 / patches / 109-ipsec_nat_traversal.patch
1 packaging/utils/nattpatch 2.4
2 Index: linux-2.4.35.4/include/net/sock.h
3 ===================================================================
4 --- linux-2.4.35.4.orig/include/net/sock.h
5 +++ linux-2.4.35.4/include/net/sock.h
6 @@ -488,7 +488,13 @@ struct tcp_opt {
7 } bictcp;
8 };
9
10 -
11 +#if 1
12 +#define UDP_OPT_IN_SOCK 1
13 +struct udp_opt {
14 + __u32 esp_in_udp;
15 +};
16 +#endif
17 +
18 /*
19 * This structure really needs to be cleaned up.
20 * Most of it is for TCP, and not used by any of
21 @@ -655,6 +661,9 @@ struct sock {
22 #if defined(CONFIG_SPX) || defined (CONFIG_SPX_MODULE)
23 struct spx_opt af_spx;
24 #endif /* CONFIG_SPX */
25 +#if 1
26 + struct udp_opt af_udp;
27 +#endif
28
29 } tp_pinfo;
30
31 Index: linux-2.4.35.4/net/Config.in
32 ===================================================================
33 --- linux-2.4.35.4.orig/net/Config.in
34 +++ linux-2.4.35.4/net/Config.in
35 @@ -104,4 +104,6 @@ comment 'Network testing'
36 dep_tristate 'Packet Generator (USE WITH CAUTION)' CONFIG_NET_PKTGEN $CONFIG_PROC_FS
37 endmenu
38
39 +bool 'IPSEC NAT-Traversal' CONFIG_IPSEC_NAT_TRAVERSAL
40 +
41 endmenu
42 Index: linux-2.4.35.4/net/ipv4/udp.c
43 ===================================================================
44 --- linux-2.4.35.4.orig/net/ipv4/udp.c
45 +++ linux-2.4.35.4/net/ipv4/udp.c
46 @@ -860,6 +860,9 @@ static void udp_close(struct sock *sk, l
47
48 static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
49 {
50 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
51 + struct udp_opt *tp = &(sk->tp_pinfo.af_udp);
52 +#endif
53 /*
54 * Charge it to the socket, dropping if the queue is full.
55 */
56 @@ -877,6 +880,40 @@ static int udp_queue_rcv_skb(struct sock
57 }
58 #endif
59
60 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
61 + if (tp->esp_in_udp) {
62 + /*
63 + * Set skb->sk and xmit packet to ipsec_rcv.
64 + *
65 + * If ret != 0, ipsec_rcv refused the packet (not ESPinUDP),
66 + * restore skb->sk and fall back to sock_queue_rcv_skb
67 + */
68 + struct inet_protocol *esp = NULL;
69 +
70 +#if defined(CONFIG_KLIPS) && !defined(CONFIG_KLIPS_MODULE)
71 + /* optomize only when we know it is statically linked */
72 + extern struct inet_protocol esp_protocol;
73 + esp = &esp_protocol;
74 +#else
75 + for (esp = (struct inet_protocol *)inet_protos[IPPROTO_ESP & (MAX_INET_PROTOS - 1)];
76 + (esp) && (esp->protocol != IPPROTO_ESP);
77 + esp = esp->next);
78 +#endif
79 +
80 + if (esp && esp->handler) {
81 + struct sock *sav_sk = skb->sk;
82 + skb->sk = sk;
83 + if (esp->handler(skb) == 0) {
84 + skb->sk = sav_sk;
85 + /*not sure we might count ESPinUDP as UDP...*/
86 + UDP_INC_STATS_BH(UdpInDatagrams);
87 + return 0;
88 + }
89 + skb->sk = sav_sk;
90 + }
91 + }
92 +#endif
93 +
94 if (sock_queue_rcv_skb(sk,skb)<0) {
95 UDP_INC_STATS_BH(UdpInErrors);
96 IP_INC_STATS_BH(IpInDiscards);
97 @@ -1100,13 +1137,49 @@ out:
98 return len;
99 }
100
101 +static int udp_setsockopt(struct sock *sk, int level, int optname,
102 + char *optval, int optlen)
103 +{
104 + struct udp_opt *tp = &(sk->tp_pinfo.af_udp);
105 + int val;
106 + int err = 0;
107 +
108 + if (level != SOL_UDP)
109 + return ip_setsockopt(sk, level, optname, optval, optlen);
110 +
111 + if(optlen<sizeof(int))
112 + return -EINVAL;
113 +
114 + if (get_user(val, (int *)optval))
115 + return -EFAULT;
116 +
117 + lock_sock(sk);
118 +
119 + switch(optname) {
120 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
121 +#ifndef UDP_ESPINUDP
122 +#define UDP_ESPINUDP 100
123 +#endif
124 + case UDP_ESPINUDP:
125 + tp->esp_in_udp = val;
126 + break;
127 +#endif
128 + default:
129 + err = -ENOPROTOOPT;
130 + break;
131 + }
132 +
133 + release_sock(sk);
134 + return err;
135 +}
136 +
137 struct proto udp_prot = {
138 name: "UDP",
139 close: udp_close,
140 connect: udp_connect,
141 disconnect: udp_disconnect,
142 ioctl: udp_ioctl,
143 - setsockopt: ip_setsockopt,
144 + setsockopt: udp_setsockopt,
145 getsockopt: ip_getsockopt,
146 sendmsg: udp_sendmsg,
147 recvmsg: udp_recvmsg,