*** /vol/sony/linux-2.6.16/include/net/xfrmudp.h 1969-12-31 19:00:00.000000000 -0500 --- include/net/xfrmudp.h 2006-05-12 17:18:27.000000000 -0400 *************** *** 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); *** /vol/sony/linux-2.6.16/net/ipv4/Kconfig 2006-03-20 00:53:29.000000000 -0500 --- net/ipv4/Kconfig 2006-05-12 17:18:27.000000000 -0400 *************** *** 367,372 **** --- 367,378 ---- If unsure, say N. + 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 INET_AH tristate "IP: AH transformation" select XFRM *** /vol/sony/linux-2.6.16/net/ipv4/udp.c 2006-03-20 00:53:29.000000000 -0500 --- net/ipv4/udp.c 2006-05-12 17:18:27.000000000 -0400 *************** *** 109,119 **** --- 109,122 ---- #include #include #include + #include /* * 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]; *************** *** 497,502 **** --- 500,507 ---- int err; int corkreq = up->corkflag || msg->msg_flags&MSG_MORE; + memset(&ipc, 0, sizeof(ipc)); + if (len > 0xFFFF) return -EMSGSIZE; *************** *** 658,663 **** --- 663,672 ---- ip_rt_put(rt); if (free) kfree(ipc.opt); + if(ipc.sp) { + secpath_put(ipc.sp); + ipc.sp=NULL; + } if (!err) { UDP_INC_STATS_USER(UDP_MIB_OUTDATAGRAMS); return len; *************** *** 882,887 **** --- 891,932 ---- 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,897 **** */ static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb) { ! #ifndef CONFIG_XFRM return 1; ! #else struct udp_sock *up = udp_sk(sk); struct udphdr *uh = skb->h.uh; struct iphdr *iph; --- 934,942 ---- */ static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb) { ! #if !defined(CONFIG_XFRM) && !defined(CONFIG_IPSEC_NAT_TRAVERSAL) return 1; ! #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,913 **** /* if we're overly short, let UDP handle it */ if (udpdata > skb->tail) ! return 1; /* if this is not encapsulated socket, then just return now */ if (!encap_type) ! return 1; len = skb->tail - udpdata; --- 948,958 ---- /* if we're overly short, let UDP handle it */ if (udpdata > skb->tail) ! return 2; /* if this is not encapsulated socket, then just return now */ if (!encap_type) ! return 3; len = skb->tail - udpdata; *************** *** 922,928 **** len = sizeof(struct udphdr); } else /* Must be an IKE packet.. pass it through */ ! return 1; break; case UDP_ENCAP_ESPINUDP_NON_IKE: /* Check if this is a keepalive packet. If so, eat it. */ --- 967,973 ---- len = sizeof(struct udphdr); } else /* Must be an IKE packet.. pass it through */ ! return 4; break; case UDP_ENCAP_ESPINUDP_NON_IKE: /* Check if this is a keepalive packet. If so, eat it. */ *************** *** 935,941 **** len = sizeof(struct udphdr) + 2 * sizeof(u32); } else /* Must be an IKE packet.. pass it through */ ! return 1; break; } --- 980,986 ---- len = sizeof(struct udphdr) + 2 * sizeof(u32); } else /* Must be an IKE packet.. pass it through */ ! return 5; break; } *************** *** 1010,1018 **** 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; } /* FALLTHROUGH -- it's a UDP Packet */ --- 1055,1067 ---- return 0; } if (ret < 0) { ! 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 */ *************** *** 1102,1108 **** /* * All we need to do is get the socket, and then do a checksum. */ - int udp_rcv(struct sk_buff *skb) { struct sock *sk; --- 1151,1156 ---- *************** *** 1135,1141 **** return udp_v4_mcast_deliver(skb, uh, saddr, daddr); sk = udp_v4_lookup(saddr, uh->source, daddr, uh->dest, skb->dev->ifindex); - if (sk != NULL) { int ret = udp_queue_rcv_skb(sk, skb); sock_put(sk); --- 1183,1188 ---- *************** *** 1559,1561 **** --- 1606,1614 ---- 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 +