--- plain26/net/ipv4/udp.c.orig 2006-12-28 20:53:17.000000000 -0500 +++ plain26/net/ipv4/udp.c 2007-05-11 10:22:50.000000000 -0400 @@ -108,6 +108,7 @@ #include #include #include +#include /* * Snmp MIB for the UDP layer @@ -881,6 +882,31 @@ sk_common_release(sk); } +#if defined(CONFIG_XFRM) || defined(CONFIG_IPSEC_NAT_TRAVERSAL) + +static xfrm4_rcv_encap_t xfrm4_rcv_encap_func = NULL; +int udp4_register_esp_rcvencap(xfrm4_rcv_encap_t func + , xfrm4_rcv_encap_t *oldfunc) +{ + if(oldfunc != NULL) { + *oldfunc = xfrm4_rcv_encap_func; + } + + xfrm4_rcv_encap_func = func; + return 0; +} + +int udp4_unregister_esp_rcvencap(xfrm4_rcv_encap_t func, xfrm4_rcv_encap_t old) +{ + if(xfrm4_rcv_encap_func != func) + return -1; + + xfrm4_rcv_encap_func = old; + 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 @@ -888,9 +914,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; struct iphdr *iph; @@ -1018,10 +1044,27 @@ return 0; } if (ret < 0) { - /* process the ESP packet */ - ret = xfrm4_rcv_encap(skb, up->encap_type); - UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS); - return -ret; + if(xfrm4_rcv_encap_func != NULL) + ret = (*xfrm4_rcv_encap_func)(skb, up->encap_type); + + switch(ret) { + case 1: + /* FALLTHROUGH to send-up */; + break; + + case 0: + /* PROCESSED, free it */ + UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS); + return 0; + + case -1: + /* PACKET wasn't for _func, or no func, pass it + * to stock function + */ + ret = xfrm4_rcv_encap(skb, up->encap_type); + UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS); + return -ret; + } } /* FALLTHROUGH -- it's a UDP Packet */ } @@ -1110,7 +1153,6 @@ /* * All we need to do is get the socket, and then do a checksum. */ - int udp_rcv(struct sk_buff *skb) { struct sock *sk; @@ -1599,3 +1641,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 +