Root/target/linux/lantiq/patches-2.6.32/240-udp_redirect.patch

1--- /dev/null
2+++ b/include/linux/udp_redirect.h
3@@ -0,0 +1,57 @@
4+#ifndef _UDP_REDIRECT_H
5+#define _UDP_REDIRECT_H
6+
7+/******************************************************************************
8+
9+ Copyright (c) 2006
10+ Infineon Technologies AG
11+ Am Campeon 1-12; 81726 Munich, Germany
12+
13+ THE DELIVERY OF THIS SOFTWARE AS WELL AS THE HEREBY GRANTED NON-EXCLUSIVE,
14+ WORLDWIDE LICENSE TO USE, COPY, MODIFY, DISTRIBUTE AND SUBLICENSE THIS
15+ SOFTWARE IS FREE OF CHARGE.
16+
17+ THE LICENSED SOFTWARE IS PROVIDED "AS IS" AND INFINEON EXPRESSLY DISCLAIMS
18+ ALL REPRESENTATIONS AND WARRANTIES, WHETHER EXPRESS OR IMPLIED, INCLUDING
19+ WITHOUT LIMITATION, WARRANTIES OR REPRESENTATIONS OF WORKMANSHIP,
20+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, DURABILITY, THAT THE
21+ OPERATING OF THE LICENSED SOFTWARE WILL BE ERROR FREE OR FREE OF ANY THIRD
22+ PARTY CLAIMS, INCLUDING WITHOUT LIMITATION CLAIMS OF THIRD PARTY INTELLECTUAL
23+ PROPERTY INFRINGEMENT.
24+
25+ EXCEPT FOR ANY LIABILITY DUE TO WILFUL ACTS OR GROSS NEGLIGENCE AND EXCEPT
26+ FOR ANY PERSONAL INJURY INFINEON SHALL IN NO EVENT BE LIABLE FOR ANY CLAIM
27+ OR DAMAGES OF ANY KIND, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
28+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29+ DEALINGS IN THE SOFTWARE.
30+
31+******************************************************************************/
32+
33+/* ============================= */
34+/* Includes */
35+/* ============================= */
36+#ifndef _LINUX_TYPES_H
37+#include <linux/types.h>
38+#endif
39+
40+
41+/* ============================= */
42+/* Definitions */
43+/* ============================= */
44+#define UDP_REDIRECT_MAGIC (void*)0x55445052L
45+
46+
47+/* ============================= */
48+/* Global variable declaration */
49+/* ============================= */
50+extern int (*udp_do_redirect_fn)(struct sock *sk, struct sk_buff *skb);
51+extern int (*udpredirect_getfrag_fn)(void *p, char * to,
52+ int offset, int fraglen, int odd,
53+ struct sk_buff *skb);
54+/* ============================= */
55+/* Global function declaration */
56+/* ============================= */
57+
58+extern int udpredirect_getfrag(void *p, char * to, int offset,
59+ int fraglen, int odd, struct sk_buff *skb);
60+#endif
61--- /dev/null
62+++ b/net/ipv4/udp_redirect_symb.c
63@@ -0,0 +1,186 @@
64+/******************************************************************************
65+
66+ Copyright (c) 2006
67+ Infineon Technologies AG
68+ Am Campeon 1-12; 81726 Munich, Germany
69+
70+ THE DELIVERY OF THIS SOFTWARE AS WELL AS THE HEREBY GRANTED NON-EXCLUSIVE,
71+ WORLDWIDE LICENSE TO USE, COPY, MODIFY, DISTRIBUTE AND SUBLICENSE THIS
72+ SOFTWARE IS FREE OF CHARGE.
73+
74+ THE LICENSED SOFTWARE IS PROVIDED "AS IS" AND INFINEON EXPRESSLY DISCLAIMS
75+ ALL REPRESENTATIONS AND WARRANTIES, WHETHER EXPRESS OR IMPLIED, INCLUDING
76+ WITHOUT LIMITATION, WARRANTIES OR REPRESENTATIONS OF WORKMANSHIP,
77+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, DURABILITY, THAT THE
78+ OPERATING OF THE LICENSED SOFTWARE WILL BE ERROR FREE OR FREE OF ANY THIRD
79+ PARTY CLAIMS, INCLUDING WITHOUT LIMITATION CLAIMS OF THIRD PARTY INTELLECTUAL
80+ PROPERTY INFRINGEMENT.
81+
82+ EXCEPT FOR ANY LIABILITY DUE TO WILFUL ACTS OR GROSS NEGLIGENCE AND EXCEPT
83+ FOR ANY PERSONAL INJURY INFINEON SHALL IN NO EVENT BE LIABLE FOR ANY CLAIM
84+ OR DAMAGES OF ANY KIND, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
85+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
86+ DEALINGS IN THE SOFTWARE.
87+
88+******************************************************************************/
89+#if defined(CONFIG_IFX_UDP_REDIRECT) || defined(CONFIG_IFX_UDP_REDIRECT_MODULE)
90+/* ============================= */
91+/* Includes */
92+/* ============================= */
93+#include <net/checksum.h>
94+#include <net/udp.h>
95+#include <linux/module.h>
96+#include <linux/skbuff.h>
97+#include <linux/udp_redirect.h>
98+
99+/* ============================= */
100+/* Global variable definition */
101+/* ============================= */
102+int (*udpredirect_getfrag_fn) (void *p, char * to, int offset,
103+ int fraglen, int odd, struct sk_buff *skb) = NULL;
104+int (*udp_do_redirect_fn)(struct sock *sk, struct sk_buff *skb) = NULL;
105+
106+/* ============================= */
107+/* Local type definitions */
108+/* ============================= */
109+struct udpfakehdr
110+{
111+ struct udphdr uh;
112+ u32 saddr;
113+ u32 daddr;
114+ struct iovec *iov;
115+ u32 wcheck;
116+};
117+
118+/* ============================= */
119+/* Local function declaration */
120+/* ============================= */
121+static int udpredirect_csum_partial_copy_fromiovecend(unsigned char *kdata,
122+ struct iovec *iov, int offset, unsigned int len, __wsum *csump);
123+
124+static int udpredirect_memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, int offset,
125+ int len);
126+
127+/* ============================= */
128+/* Global function definition */
129+/* ============================= */
130+
131+/*
132+ Copy of udp_getfrag() from udp.c
133+ This function exists because no copy_from_user() is needed for udpredirect.
134+*/
135+
136+int
137+udpredirect_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb)
138+{
139+ struct iovec *iov = from;
140+
141+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
142+ if (udpredirect_memcpy_fromiovecend(to, iov, offset, len) < 0)
143+ return -EFAULT;
144+ } else {
145+ __wsum csum = 0;
146+ if (udpredirect_csum_partial_copy_fromiovecend(to, iov, offset, len, &csum) < 0)
147+ return -EFAULT;
148+ skb->csum = csum_block_add(skb->csum, csum, odd);
149+ }
150+ return 0;
151+}
152+
153+static int udpredirect_memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, int offset,
154+ int len)
155+{
156+ /* Skip over the finished iovecs */
157+ while (offset >= iov->iov_len) {
158+ offset -= iov->iov_len;
159+ iov++;
160+ }
161+
162+ while (len > 0) {
163+ u8 __user *base = iov->iov_base + offset;
164+ int copy = min_t(unsigned int, len, iov->iov_len - offset);
165+
166+ offset = 0;
167+ memcpy(kdata, base, copy);
168+ len -= copy;
169+ kdata += copy;
170+ iov++;
171+ }
172+
173+ return 0;
174+}
175+
176+/*
177+ Copy of csum_partial_copy_fromiovecend() from iovec.c
178+ This function exists because no copy_from_user() is needed for udpredirect.
179+*/
180+
181+int udpredirect_csum_partial_copy_fromiovecend(unsigned char *kdata, struct iovec *iov,
182+ int offset, unsigned int len, __wsum *csump)
183+{
184+ __wsum csum = *csump;
185+ int partial_cnt = 0, err = 0;
186+
187+ /* Skip over the finished iovecs */
188+ while (offset >= iov->iov_len) {
189+ offset -= iov->iov_len;
190+ iov++;
191+ }
192+
193+ while (len > 0) {
194+ u8 __user *base = iov->iov_base + offset;
195+ int copy = min_t(unsigned int, len, iov->iov_len - offset);
196+
197+ offset = 0;
198+
199+ /* There is a remnant from previous iov. */
200+ if (partial_cnt) {
201+ int par_len = 4 - partial_cnt;
202+
203+ /* iov component is too short ... */
204+ if (par_len > copy) {
205+ memcpy(kdata, base, copy);
206+ kdata += copy;
207+ base += copy;
208+ partial_cnt += copy;
209+ len -= copy;
210+ iov++;
211+ if (len)
212+ continue;
213+ *csump = csum_partial(kdata - partial_cnt,
214+ partial_cnt, csum);
215+ goto out;
216+ }
217+ memcpy(kdata, base, par_len);
218+ csum = csum_partial(kdata - partial_cnt, 4, csum);
219+ kdata += par_len;
220+ base += par_len;
221+ copy -= par_len;
222+ len -= par_len;
223+ partial_cnt = 0;
224+ }
225+
226+ if (len > copy) {
227+ partial_cnt = copy % 4;
228+ if (partial_cnt) {
229+ copy -= partial_cnt;
230+ memcpy(kdata + copy, base + copy, partial_cnt);
231+ }
232+ }
233+
234+ if (copy) {
235+ csum = csum_partial_copy_nocheck(base, kdata, copy, csum);
236+ }
237+ len -= copy + partial_cnt;
238+ kdata += copy + partial_cnt;
239+ iov++;
240+ }
241+ *csump = csum;
242+out:
243+ return err;
244+}
245+
246+EXPORT_SYMBOL(udpredirect_getfrag);
247+EXPORT_SYMBOL(udp_do_redirect_fn);
248+EXPORT_SYMBOL(udpredirect_getfrag_fn);
249+#endif /* CONFIG_IFX_UDP_REDIRECT* */
250--- a/net/ipv4/Makefile
251+++ b/net/ipv4/Makefile
252@@ -14,6 +14,9 @@
253          inet_fragment.o
254 
255 obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o
256+ifneq ($(CONFIG_IFX_UDP_REDIRECT),)
257+obj-$(CONFIG_IFX_UDP_REDIRECT) += udp_redirect_symb.o
258+endif
259 obj-$(CONFIG_IP_FIB_HASH) += fib_hash.o
260 obj-$(CONFIG_IP_FIB_TRIE) += fib_trie.o
261 obj-$(CONFIG_PROC_FS) += proc.o
262--- a/net/ipv4/udp.c
263+++ b/net/ipv4/udp.c
264@@ -106,7 +106,11 @@
265 #include <net/xfrm.h>
266 #include "udp_impl.h"
267 
268+#if defined(CONFIG_IFX_UDP_REDIRECT) || defined(CONFIG_IFX_UDP_REDIRECT_MODULE)
269+#include <linux/udp_redirect.h>
270+#endif
271 struct udp_table udp_table;
272+
273 EXPORT_SYMBOL(udp_table);
274 
275 int sysctl_udp_mem[3] __read_mostly;
276@@ -591,7 +595,7 @@
277     u8 tos;
278     int err, is_udplite = IS_UDPLITE(sk);
279     int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
280- int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
281+ int (*getfrag)(void *, char *, int, int, int, struct sk_buff *) = NULL;
282 
283     if (len > 0xFFFF)
284         return -EMSGSIZE;
285@@ -753,6 +757,12 @@
286 
287 do_append_data:
288     up->len += ulen;
289+ /* UDPREDIRECT */
290+#if defined(CONFIG_IFX_UDP_REDIRECT) || defined(CONFIG_IFX_UDP_REDIRECT_MODULE)
291+ if(udpredirect_getfrag_fn && sk->sk_user_data == UDP_REDIRECT_MAGIC)
292+ getfrag = udpredirect_getfrag_fn;
293+ else
294+#endif /* IFX_UDP_REDIRECT */
295     getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
296     err = ip_append_data(sk, getfrag, msg->msg_iov, ulen,
297             sizeof(struct udphdr), &ipc, &rt,
298@@ -1283,6 +1293,7 @@
299     struct rtable *rt = skb_rtable(skb);
300     __be32 saddr, daddr;
301     struct net *net = dev_net(skb->dev);
302+ int ret = 0;
303 
304     /*
305      * Validate the packet.
306@@ -1315,7 +1326,16 @@
307     sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
308 
309     if (sk != NULL) {
310- int ret = udp_queue_rcv_skb(sk, skb);
311+ /* UDPREDIRECT */
312+#if defined(CONFIG_IFX_UDP_REDIRECT) || defined(CONFIG_IFX_UDP_REDIRECT_MODULE)
313+ if(udp_do_redirect_fn && sk->sk_user_data == UDP_REDIRECT_MAGIC)
314+ {
315+ udp_do_redirect_fn(sk,skb);
316+ kfree_skb(skb);
317+ return(0);
318+ }
319+#endif
320+ ret = udp_queue_rcv_skb(sk, skb);
321         sock_put(sk);
322 
323         /* a return value > 0 means to resubmit the input, but
324@@ -1610,7 +1630,7 @@
325 #endif
326 };
327 EXPORT_SYMBOL(udp_prot);
328-
329+EXPORT_SYMBOL(udp_rcv);
330 /* ------------------------------------------------------------------------ */
331 #ifdef CONFIG_PROC_FS
332 
333--- a/net/Kconfig
334+++ b/net/Kconfig
335@@ -72,6 +72,12 @@
336 
337       Short answer: say Y.
338 
339+config IFX_UDP_REDIRECT
340+ bool "IFX Kernel Packet Interface for UDP redirection"
341+ help
342+ You can say Y here if you want to use hooks from kernel for
343+ UDP redirection.
344+
345 if INET
346 source "net/ipv4/Kconfig"
347 source "net/ipv6/Kconfig"
348

Archive Download this file



interactive