summaryrefslogtreecommitdiffstats
path: root/openwrt/target/linux/generic-2.6/patches/102-openswan-2.4.0.kernel-2.6-natt.patch
blob: 6d6939beee20013689e3dfa5801be19acb8f9a5c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
diff -Nur linux-2.6.16/include/net/xfrmudp.h linux-2.6.16-owrt/include/net/xfrmudp.h
--- linux-2.6.16/include/net/xfrmudp.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.16-owrt/include/net/xfrmudp.h	2006-03-22 21:39:54.000000000 +0100
@@ -0,0 +1,10 @@
+/*
+ * pointer to function for type that xfrm4_input wants, to permit
+ * decoupling of XFRM from udp.c
+ */
+#define HAVE_XFRM4_UDP_REGISTER
+
+typedef int (*xfrm4_rcv_encap_t)(struct sk_buff *skb, __u16 encap_type);
+extern int udp4_register_esp_rcvencap(xfrm4_rcv_encap_t func
+				      , xfrm4_rcv_encap_t *oldfunc);
+extern int udp4_unregister_esp_rcvencap(xfrm4_rcv_encap_t func);
diff -Nur linux-2.6.16/net/ipv4/Kconfig linux-2.6.16-owrt/net/ipv4/Kconfig
--- linux-2.6.16/net/ipv4/Kconfig	2006-03-20 06:53:29.000000000 +0100
+++ linux-2.6.16-owrt/net/ipv4/Kconfig	2006-03-22 21:49:04.000000000 +0100
@@ -271,6 +271,12 @@
 	  Network), but can be distributed all over the Internet. If you want
 	  to do that, say Y here and to "IP multicast routing" below.
 
+config IPSEC_NAT_TRAVERSAL
+	bool "IPSEC NAT-Traversal (KLIPS compatible)"
+	depends on INET
+	---help---
+          Includes support for RFC3947/RFC3948 NAT-Traversal of ESP over UDP.
+
 config IP_MROUTE
 	bool "IP: multicast routing"
 	depends on IP_MULTICAST
diff -Nur linux-2.6.16/net/ipv4/udp.c linux-2.6.16-owrt/net/ipv4/udp.c
--- linux-2.6.16/net/ipv4/udp.c	2006-03-20 06:53:29.000000000 +0100
+++ linux-2.6.16-owrt/net/ipv4/udp.c	2006-03-22 21:39:54.000000000 +0100
@@ -109,11 +109,14 @@
 #include <net/inet_common.h>
 #include <net/checksum.h>
 #include <net/xfrm.h>
+#include <net/xfrmudp.h>
 
 /*
  *	Snmp MIB for the UDP layer
  */
 
+static xfrm4_rcv_encap_t xfrm4_rcv_encap_func;
+
 DEFINE_SNMP_STAT(struct udp_mib, udp_statistics) __read_mostly;
 
 struct hlist_head udp_hash[UDP_HTABLE_SIZE];
@@ -882,6 +885,42 @@
 	sk_common_release(sk);
 }
 
+#if defined(CONFIG_XFRM) || defined(CONFIG_IPSEC_NAT_TRAVERSAL)
+
+/* if XFRM isn't a module, then register it directly. */
+#if 0 && !defined(CONFIG_XFRM_MODULE) && !defined(CONFIG_IPSEC_NAT_TRAVERSAL)
+static xfrm4_rcv_encap_t xfrm4_rcv_encap_func = xfrm4_rcv_encap;
+#else
+static xfrm4_rcv_encap_t xfrm4_rcv_encap_func = NULL;
+#endif
+
+int udp4_register_esp_rcvencap(xfrm4_rcv_encap_t func
+			       , xfrm4_rcv_encap_t *oldfunc)
+{
+  if(oldfunc != NULL) {
+    *oldfunc = xfrm4_rcv_encap_func;
+  }
+
+#if 0
+  if(xfrm4_rcv_encap_func != NULL)
+    return -1;
+#endif
+
+  xfrm4_rcv_encap_func = func;
+  return 0;
+}
+
+int udp4_unregister_esp_rcvencap(xfrm4_rcv_encap_t func)
+{
+  if(xfrm4_rcv_encap_func != func)
+    return -1;
+
+  xfrm4_rcv_encap_func = NULL;
+  return 0;
+}
+#endif /* CONFIG_XFRM_MODULE || CONFIG_IPSEC_NAT_TRAVERSAL */
+
+
 /* return:
  * 	1  if the the UDP system should process it
  *	0  if we should drop this packet
@@ -889,9 +928,9 @@
  */
 static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
 {
-#ifndef CONFIG_XFRM
+#if !defined(CONFIG_XFRM) && !defined(CONFIG_IPSEC_NAT_TRAVERSAL)
 	return 1; 
-#else
+#else /* either CONFIG_XFRM or CONFIG_IPSEC_NAT_TRAVERSAL */
 	struct udp_sock *up = udp_sk(sk);
   	struct udphdr *uh = skb->h.uh;
 	struct iphdr *iph;
@@ -903,11 +942,11 @@
 
 	/* if we're overly short, let UDP handle it */
 	if (udpdata > skb->tail)
-		return 1;
+		return 2;
 
 	/* if this is not encapsulated socket, then just return now */
 	if (!encap_type)
-		return 1;
+		return 3;
 
 	len = skb->tail - udpdata;
 
@@ -922,7 +961,7 @@
 			len = sizeof(struct udphdr);
 		} else
 			/* Must be an IKE packet.. pass it through */
-			return 1;
+			return 4;
 		break;
 	case UDP_ENCAP_ESPINUDP_NON_IKE:
 		/* Check if this is a keepalive packet.  If so, eat it. */
@@ -935,7 +974,7 @@
 			len = sizeof(struct udphdr) + 2 * sizeof(u32);
 		} else
 			/* Must be an IKE packet.. pass it through */
-			return 1;
+			return 5;
 		break;
 	}
 
@@ -946,6 +985,8 @@
 	 */
 	if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
 		return 0;
+	if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+		return 0;
 
 	/* Now we can update and verify the packet length... */
 	iph = skb->nh.iph;
@@ -1010,9 +1051,13 @@
 			return 0;
 		}
 		if (ret < 0) {
-			/* process the ESP packet */
-			ret = xfrm4_rcv_encap(skb, up->encap_type);
-			UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS);
+			if(xfrm4_rcv_encap_func != NULL) {
+			  ret = (*xfrm4_rcv_encap_func)(skb, up->encap_type);
+			  UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS);
+			} else {
+			  UDP_INC_STATS_BH(UDP_MIB_INERRORS);
+			  ret = 1;
+			}
 			return -ret;
 		}
 		/* FALLTHROUGH -- it's a UDP Packet */
@@ -1559,3 +1604,9 @@
 EXPORT_SYMBOL(udp_proc_register);
 EXPORT_SYMBOL(udp_proc_unregister);
 #endif
+
+#if defined(CONFIG_IPSEC_NAT_TRAVERSAL)
+EXPORT_SYMBOL(udp4_register_esp_rcvencap);
+EXPORT_SYMBOL(udp4_unregister_esp_rcvencap);
+#endif
+