2 +++ b/include/linux/udp_redirect.h
4 +#ifndef _UDP_REDIRECT_H
5 +#define _UDP_REDIRECT_H
7 +/******************************************************************************
10 + Infineon Technologies AG
11 + Am Campeon 1-12; 81726 Munich, Germany
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.
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.
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.
31 +******************************************************************************/
33 +/* ============================= */
35 +/* ============================= */
36 +#ifndef _LINUX_TYPES_H
37 +#include <linux/types.h>
41 +/* ============================= */
43 +/* ============================= */
44 +#define UDP_REDIRECT_MAGIC (void*)0x55445052L
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 +/* ============================= */
58 +extern int udpredirect_getfrag(void *p, char * to, int offset,
59 + int fraglen, int odd, struct sk_buff *skb);
62 +++ b/net/ipv4/udp_redirect_symb.c
64 +/******************************************************************************
67 + Infineon Technologies AG
68 + Am Campeon 1-12; 81726 Munich, Germany
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.
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.
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.
88 +******************************************************************************/
89 +#if defined(CONFIG_IFX_UDP_REDIRECT) || defined(CONFIG_IFX_UDP_REDIRECT_MODULE)
90 +/* ============================= */
92 +/* ============================= */
93 +#include <net/checksum.h>
95 +#include <linux/module.h>
96 +#include <linux/skbuff.h>
97 +#include <linux/udp_redirect.h>
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;
106 +/* ============================= */
107 +/* Local type definitions */
108 +/* ============================= */
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);
124 +static int udpredirect_memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, int offset,
127 +/* ============================= */
128 +/* Global function definition */
129 +/* ============================= */
132 + Copy of udp_getfrag() from udp.c
133 + This function exists because no copy_from_user() is needed for udpredirect.
137 +udpredirect_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb)
139 + struct iovec *iov = from;
141 + if (skb->ip_summed == CHECKSUM_PARTIAL) {
142 + if (udpredirect_memcpy_fromiovecend(to, iov, offset, len) < 0)
146 + if (udpredirect_csum_partial_copy_fromiovecend(to, iov, offset, len, &csum) < 0)
148 + skb->csum = csum_block_add(skb->csum, csum, odd);
153 +static int udpredirect_memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, int offset,
156 + /* Skip over the finished iovecs */
157 + while (offset >= iov->iov_len) {
158 + offset -= iov->iov_len;
163 + u8 __user *base = iov->iov_base + offset;
164 + int copy = min_t(unsigned int, len, iov->iov_len - offset);
167 + memcpy(kdata, base, copy);
177 + Copy of csum_partial_copy_fromiovecend() from iovec.c
178 + This function exists because no copy_from_user() is needed for udpredirect.
181 +int udpredirect_csum_partial_copy_fromiovecend(unsigned char *kdata, struct iovec *iov,
182 + int offset, unsigned int len, __wsum *csump)
184 + __wsum csum = *csump;
185 + int partial_cnt = 0, err = 0;
187 + /* Skip over the finished iovecs */
188 + while (offset >= iov->iov_len) {
189 + offset -= iov->iov_len;
194 + u8 __user *base = iov->iov_base + offset;
195 + int copy = min_t(unsigned int, len, iov->iov_len - offset);
199 + /* There is a remnant from previous iov. */
201 + int par_len = 4 - partial_cnt;
203 + /* iov component is too short ... */
204 + if (par_len > copy) {
205 + memcpy(kdata, base, copy);
208 + partial_cnt += copy;
213 + *csump = csum_partial(kdata - partial_cnt,
214 + partial_cnt, csum);
217 + memcpy(kdata, base, par_len);
218 + csum = csum_partial(kdata - partial_cnt, 4, csum);
227 + partial_cnt = copy % 4;
229 + copy -= partial_cnt;
230 + memcpy(kdata + copy, base + copy, partial_cnt);
235 + csum = csum_partial_copy_nocheck(base, kdata, copy, csum);
237 + len -= copy + partial_cnt;
238 + kdata += copy + partial_cnt;
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
255 obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o
256 +ifneq ($(CONFIG_IFX_UDP_REDIRECT),)
257 +obj-$(CONFIG_IFX_UDP_REDIRECT) += udp_redirect_symb.o
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
265 #include <net/xfrm.h>
266 #include "udp_impl.h"
268 +#if defined(CONFIG_IFX_UDP_REDIRECT) || defined(CONFIG_IFX_UDP_REDIRECT_MODULE)
269 +#include <linux/udp_redirect.h>
272 struct udp_table udp_table __read_mostly;
273 EXPORT_SYMBOL(udp_table);
277 int err, is_udplite = IS_UDPLITE(sk);
278 int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
279 - int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
280 + int (*getfrag)(void *, char *, int, int, int, struct sk_buff *) = NULL;
289 +#if defined(CONFIG_IFX_UDP_REDIRECT) || defined(CONFIG_IFX_UDP_REDIRECT_MODULE)
290 + if(udpredirect_getfrag_fn && sk->sk_user_data == UDP_REDIRECT_MAGIC)
291 + getfrag = udpredirect_getfrag_fn;
293 +#endif /* IFX_UDP_REDIRECT */
294 getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
295 err = ip_append_data(sk, getfrag, msg->msg_iov, ulen,
296 sizeof(struct udphdr), &ipc, &rt,
297 @@ -1573,6 +1583,7 @@
298 struct rtable *rt = skb_rtable(skb);
300 struct net *net = dev_net(skb->dev);
304 * Validate the packet.
305 @@ -1605,7 +1616,16 @@
306 sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
309 - int ret = udp_queue_rcv_skb(sk, skb);
311 +#if defined(CONFIG_IFX_UDP_REDIRECT) || defined(CONFIG_IFX_UDP_REDIRECT_MODULE)
312 + if(udp_do_redirect_fn && sk->sk_user_data == UDP_REDIRECT_MAGIC)
314 + udp_do_redirect_fn(sk,skb);
319 + ret = udp_queue_rcv_skb(sk, skb);
322 /* a return value > 0 means to resubmit the input, but
323 @@ -1902,7 +1922,7 @@
324 .clear_sk = sk_prot_clear_portaddr_nulls,
326 EXPORT_SYMBOL(udp_prot);
328 +EXPORT_SYMBOL(udp_rcv);
329 /* ------------------------------------------------------------------------ */
330 #ifdef CONFIG_PROC_FS
338 +config IFX_UDP_REDIRECT
339 + bool "IFX Kernel Packet Interface for UDP redirection"
341 + You can say Y here if you want to use hooks from kernel for
345 source "net/ipv4/Kconfig"
346 source "net/ipv6/Kconfig"