| 1 | packaging/utils/nattpatch 2.4 |
| 2 | --- a/include/net/sock.h |
| 3 | +++ b/include/net/sock.h |
| 4 | @@ -488,7 +488,13 @@ struct tcp_opt { |
| 5 | } bictcp; |
| 6 | }; |
| 7 | |
| 8 | - |
| 9 | +#if 1 |
| 10 | +#define UDP_OPT_IN_SOCK 1 |
| 11 | +struct udp_opt { |
| 12 | + __u32 esp_in_udp; |
| 13 | +}; |
| 14 | +#endif |
| 15 | + |
| 16 | /* |
| 17 | * This structure really needs to be cleaned up. |
| 18 | * Most of it is for TCP, and not used by any of |
| 19 | @@ -655,6 +661,9 @@ struct sock { |
| 20 | #if defined(CONFIG_SPX) || defined (CONFIG_SPX_MODULE) |
| 21 | struct spx_opt af_spx; |
| 22 | #endif /* CONFIG_SPX */ |
| 23 | +#if 1 |
| 24 | + struct udp_opt af_udp; |
| 25 | +#endif |
| 26 | |
| 27 | } tp_pinfo; |
| 28 | |
| 29 | --- a/net/Config.in |
| 30 | +++ b/net/Config.in |
| 31 | @@ -104,4 +104,6 @@ comment 'Network testing' |
| 32 | dep_tristate 'Packet Generator (USE WITH CAUTION)' CONFIG_NET_PKTGEN $CONFIG_PROC_FS |
| 33 | endmenu |
| 34 | |
| 35 | +bool 'IPSEC NAT-Traversal' CONFIG_IPSEC_NAT_TRAVERSAL |
| 36 | + |
| 37 | endmenu |
| 38 | --- a/net/ipv4/udp.c |
| 39 | +++ b/net/ipv4/udp.c |
| 40 | @@ -860,6 +860,9 @@ static void udp_close(struct sock *sk, l |
| 41 | |
| 42 | static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) |
| 43 | { |
| 44 | +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL |
| 45 | + struct udp_opt *tp = &(sk->tp_pinfo.af_udp); |
| 46 | +#endif |
| 47 | /* |
| 48 | * Charge it to the socket, dropping if the queue is full. |
| 49 | */ |
| 50 | @@ -877,6 +880,40 @@ static int udp_queue_rcv_skb(struct sock |
| 51 | } |
| 52 | #endif |
| 53 | |
| 54 | +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL |
| 55 | + if (tp->esp_in_udp) { |
| 56 | + /* |
| 57 | + * Set skb->sk and xmit packet to ipsec_rcv. |
| 58 | + * |
| 59 | + * If ret != 0, ipsec_rcv refused the packet (not ESPinUDP), |
| 60 | + * restore skb->sk and fall back to sock_queue_rcv_skb |
| 61 | + */ |
| 62 | + struct inet_protocol *esp = NULL; |
| 63 | + |
| 64 | +#if defined(CONFIG_KLIPS) && !defined(CONFIG_KLIPS_MODULE) |
| 65 | + /* optomize only when we know it is statically linked */ |
| 66 | + extern struct inet_protocol esp_protocol; |
| 67 | + esp = &esp_protocol; |
| 68 | +#else |
| 69 | + for (esp = (struct inet_protocol *)inet_protos[IPPROTO_ESP & (MAX_INET_PROTOS - 1)]; |
| 70 | + (esp) && (esp->protocol != IPPROTO_ESP); |
| 71 | + esp = esp->next); |
| 72 | +#endif |
| 73 | + |
| 74 | + if (esp && esp->handler) { |
| 75 | + struct sock *sav_sk = skb->sk; |
| 76 | + skb->sk = sk; |
| 77 | + if (esp->handler(skb) == 0) { |
| 78 | + skb->sk = sav_sk; |
| 79 | + /*not sure we might count ESPinUDP as UDP...*/ |
| 80 | + UDP_INC_STATS_BH(UdpInDatagrams); |
| 81 | + return 0; |
| 82 | + } |
| 83 | + skb->sk = sav_sk; |
| 84 | + } |
| 85 | + } |
| 86 | +#endif |
| 87 | + |
| 88 | if (sock_queue_rcv_skb(sk,skb)<0) { |
| 89 | UDP_INC_STATS_BH(UdpInErrors); |
| 90 | IP_INC_STATS_BH(IpInDiscards); |
| 91 | @@ -1100,13 +1137,49 @@ out: |
| 92 | return len; |
| 93 | } |
| 94 | |
| 95 | +static int udp_setsockopt(struct sock *sk, int level, int optname, |
| 96 | + char *optval, int optlen) |
| 97 | +{ |
| 98 | + struct udp_opt *tp = &(sk->tp_pinfo.af_udp); |
| 99 | + int val; |
| 100 | + int err = 0; |
| 101 | + |
| 102 | + if (level != SOL_UDP) |
| 103 | + return ip_setsockopt(sk, level, optname, optval, optlen); |
| 104 | + |
| 105 | + if(optlen<sizeof(int)) |
| 106 | + return -EINVAL; |
| 107 | + |
| 108 | + if (get_user(val, (int *)optval)) |
| 109 | + return -EFAULT; |
| 110 | + |
| 111 | + lock_sock(sk); |
| 112 | + |
| 113 | + switch(optname) { |
| 114 | +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL |
| 115 | +#ifndef UDP_ESPINUDP |
| 116 | +#define UDP_ESPINUDP 100 |
| 117 | +#endif |
| 118 | + case UDP_ESPINUDP: |
| 119 | + tp->esp_in_udp = val; |
| 120 | + break; |
| 121 | +#endif |
| 122 | + default: |
| 123 | + err = -ENOPROTOOPT; |
| 124 | + break; |
| 125 | + } |
| 126 | + |
| 127 | + release_sock(sk); |
| 128 | + return err; |
| 129 | +} |
| 130 | + |
| 131 | struct proto udp_prot = { |
| 132 | name: "UDP", |
| 133 | close: udp_close, |
| 134 | connect: udp_connect, |
| 135 | disconnect: udp_disconnect, |
| 136 | ioctl: udp_ioctl, |
| 137 | - setsockopt: ip_setsockopt, |
| 138 | + setsockopt: udp_setsockopt, |
| 139 | getsockopt: ip_getsockopt, |
| 140 | sendmsg: udp_sendmsg, |
| 141 | recvmsg: udp_recvmsg, |
| 142 | |