OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / freeswan / klips / patches2.3 / net.ipv4.udp.c
1 --- ./net/ipv4/udp.c    2002/02/26 14:54:22     1.2
2 +++ ./net/ipv4/udp.c    2002/05/22 12:14:58
3 @@ -777,6 +777,9 @@
4  
5  static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
6  {
7 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
8 +       struct udp_opt *tp =  &(sk->tp_pinfo.af_udp);
9 +#endif
10         /*
11          *      Charge it to the socket, dropping if the queue is full.
12          */
13 @@ -794,6 +797,38 @@
14         }
15  #endif
16  
17 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
18 +       if (tp->esp_in_udp) {
19 +               /*
20 +                * Set skb->sk and xmit packet to ipsec_rcv.
21 +                *
22 +                * If ret != 0, ipsec_rcv refused the packet (not ESPinUDP),
23 +                * restore skb->sk and fall back to sock_queue_rcv_skb
24 +                */
25 +               struct inet_protocol *esp = NULL;
26 +
27 +#ifdef CONFIG_IPSEC_MODULE
28 +               for (esp = (struct inet_protocol *)inet_protos[IPPROTO_ESP & (MAX_INET_PROTOS - 1)];
29 +                       (esp) && (esp->protocol != IPPROTO_ESP);
30 +                       esp = esp->next);
31 +#else
32 +               extern struct inet_protocol esp_protocol;
33 +               esp = &esp_protocol;
34 +#endif
35 +
36 +               if (esp && esp->handler) {
37 +                       struct sock *sav_sk = skb->sk;
38 +                       skb->sk = sk;
39 +                       if (esp->handler(skb) == 0) {
40 +                               skb->sk = sav_sk;
41 +                               /* not sure we might count ESPinUDP as UDP... */
42 +                               UDP_INC_STATS_BH(UdpInDatagrams);
43 +                               return 0;
44 +                       }
45 +                       skb->sk = sav_sk;
46 +               }
47 +       }
48 +#endif
49         if (sock_queue_rcv_skb(sk,skb)<0) {
50                 UDP_INC_STATS_BH(UdpInErrors);
51                 IP_INC_STATS_BH(IpInDiscards);
52 @@ -1010,13 +1045,55 @@
53         return len;
54  }
55  
56 +#if 1
57 +static int udp_setsockopt(struct sock *sk, int level, int optname,
58 +       char *optval, int optlen)
59 +{
60 +       struct udp_opt *tp = &(sk->tp_pinfo.af_udp);
61 +       int val;
62 +       int err = 0;
63 +
64 +       if (level != SOL_UDP)
65 +               return ip_setsockopt(sk, level, optname, optval, optlen);
66 +
67 +       if(optlen<sizeof(int))
68 +               return -EINVAL;
69 +
70 +       if (get_user(val, (int *)optval))
71 +               return -EFAULT;
72 +       
73 +       lock_sock(sk);
74 +
75 +       switch(optname) {
76 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
77 +#ifndef UDP_ESPINUDP
78 +#define UDP_ESPINUDP 100
79 +#endif
80 +               case UDP_ESPINUDP:
81 +                       tp->esp_in_udp = val;
82 +                       break;
83 +#endif
84 +               default:
85 +                       err = -ENOPROTOOPT;
86 +                       break;
87 +       }
88 +
89 +       release_sock(sk);
90 +       return err;
91 +}
92 +#endif
93 +
94  struct proto udp_prot = {
95         name:           "UDP",
96         close:          udp_close,
97         connect:        udp_connect,
98         disconnect:     udp_disconnect,
99         ioctl:          udp_ioctl,
100 +#if 1
101 +       setsockopt:     udp_setsockopt,
102 +#else
103         setsockopt:     ip_setsockopt,
104 +#endif
105         getsockopt:     ip_getsockopt,
106         sendmsg:        udp_sendmsg,
107         recvmsg:        udp_recvmsg,