aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/udp.c156
-rw-r--r--net/ipv4/xfrm4_input.c114
2 files changed, 130 insertions, 140 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index b9276f8bdac5..4ec4a25a8d0c 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -920,108 +920,6 @@ int udp_disconnect(struct sock *sk, int flags)
920 return 0; 920 return 0;
921} 921}
922 922
923/* return:
924 * 1 if the UDP system should process it
925 * 0 if we should drop this packet
926 * -1 if it should get processed by xfrm4_rcv_encap
927 * -2 if it should get processed by l2tp
928 */
929static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
930{
931 struct udp_sock *up = udp_sk(sk);
932 struct udphdr *uh;
933 struct iphdr *iph;
934 int iphlen, len;
935
936 __u8 *udpdata;
937 __be32 *udpdata32;
938 __u16 encap_type = up->encap_type;
939
940 /* if we're overly short, let UDP handle it */
941 len = skb->len - sizeof(struct udphdr);
942 if (len <= 0)
943 return 1;
944
945 /* if this is not encapsulated socket, then just return now */
946 if (!encap_type)
947 return 1;
948
949 /* If this is a paged skb, make sure we pull up
950 * whatever data we need to look at. */
951 if (!pskb_may_pull(skb, sizeof(struct udphdr) + min(len, 8)))
952 return 1;
953
954 /* Now we can get the pointers */
955 uh = udp_hdr(skb);
956 udpdata = (__u8 *)uh + sizeof(struct udphdr);
957 udpdata32 = (__be32 *)udpdata;
958
959 switch (encap_type) {
960 default:
961 case UDP_ENCAP_ESPINUDP:
962 /* Check if this is a keepalive packet. If so, eat it. */
963 if (len == 1 && udpdata[0] == 0xff) {
964 return 0;
965 } else if (len > sizeof(struct ip_esp_hdr) && udpdata32[0] != 0) {
966 /* ESP Packet without Non-ESP header */
967 len = sizeof(struct udphdr);
968 } else
969 /* Must be an IKE packet.. pass it through */
970 return 1;
971 break;
972 case UDP_ENCAP_ESPINUDP_NON_IKE:
973 /* Check if this is a keepalive packet. If so, eat it. */
974 if (len == 1 && udpdata[0] == 0xff) {
975 return 0;
976 } else if (len > 2 * sizeof(u32) + sizeof(struct ip_esp_hdr) &&
977 udpdata32[0] == 0 && udpdata32[1] == 0) {
978
979 /* ESP Packet with Non-IKE marker */
980 len = sizeof(struct udphdr) + 2 * sizeof(u32);
981 } else
982 /* Must be an IKE packet.. pass it through */
983 return 1;
984 break;
985 case UDP_ENCAP_L2TPINUDP:
986 /* Let caller know to send this to l2tp */
987 return -2;
988 }
989
990#ifndef CONFIG_XFRM
991 return 1;
992#else
993 /* At this point we are sure that this is an ESPinUDP packet,
994 * so we need to remove 'len' bytes from the packet (the UDP
995 * header and optional ESP marker bytes) and then modify the
996 * protocol to ESP, and then call into the transform receiver.
997 */
998 if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
999 return 0;
1000
1001 /* Now we can update and verify the packet length... */
1002 iph = ip_hdr(skb);
1003 iphlen = iph->ihl << 2;
1004 iph->tot_len = htons(ntohs(iph->tot_len) - len);
1005 if (skb->len < iphlen + len) {
1006 /* packet is too small!?! */
1007 return 0;
1008 }
1009
1010 /* pull the data buffer up to the ESP header and set the
1011 * transport header to point to ESP. Keep UDP on the stack
1012 * for later.
1013 */
1014 __skb_pull(skb, len);
1015 skb_reset_transport_header(skb);
1016
1017 /* modify the protocol (it's ESP!) */
1018 iph->protocol = IPPROTO_ESP;
1019
1020 /* and let the caller know to send this into the ESP processor... */
1021 return -1;
1022#endif
1023}
1024
1025/* returns: 923/* returns:
1026 * -1: error 924 * -1: error
1027 * 0: success 925 * 0: success
@@ -1044,44 +942,36 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
1044 942
1045 if (up->encap_type) { 943 if (up->encap_type) {
1046 /* 944 /*
1047 * This is an encapsulation socket, so let's see if this is 945 * This is an encapsulation socket so pass the skb to
1048 * an encapsulated packet. 946 * the socket's udp_encap_rcv() hook. Otherwise, just
1049 * If it's a keepalive packet, then just eat it. 947 * fall through and pass this up the UDP socket.
1050 * If it's an encapsulateed packet, then pass it to the 948 * up->encap_rcv() returns the following value:
1051 * IPsec xfrm input and return the response 949 * =0 if skb was successfully passed to the encap
1052 * appropriately. Otherwise, just fall through and 950 * handler or was discarded by it.
1053 * pass this up the UDP socket. 951 * >0 if skb should be passed on to UDP.
952 * <0 if skb should be resubmitted as proto -N
1054 */ 953 */
1055 int ret; 954 unsigned int len;
1056 955
1057 ret = udp_encap_rcv(sk, skb); 956 /* if we're overly short, let UDP handle it */
1058 if (ret == 0) { 957 len = skb->len - sizeof(struct udphdr);
1059 /* Eat the packet .. */ 958 if (len <= 0)
1060 kfree_skb(skb); 959 goto udp;
1061 return 0; 960
1062 } 961 if (up->encap_rcv != NULL) {
1063 if (ret == -1) { 962 int ret;
1064 /* process the ESP packet */ 963
1065 ret = xfrm4_rcv_encap(skb, up->encap_type); 964 ret = (*up->encap_rcv)(sk, skb);
1066 UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag); 965 if (ret <= 0) {
1067 return -ret; 966 UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag);
1068 } 967 return -ret;
1069 if (ret == -2) {
1070 /* process the L2TP packet */
1071 if (up->encap_rcv != NULL) {
1072 ret = (*up->encap_rcv)(sk, skb);
1073 if (ret <= 0) {
1074 UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag);
1075 return ret;
1076 }
1077
1078 /* FALLTHROUGH -- pass up as UDP packet */
1079 } 968 }
1080 } 969 }
1081 970
1082 /* FALLTHROUGH -- it's a UDP Packet */ 971 /* FALLTHROUGH -- it's a UDP Packet */
1083 } 972 }
1084 973
974udp:
1085 /* 975 /*
1086 * UDP-Lite specific tests, ignored on UDP sockets 976 * UDP-Lite specific tests, ignored on UDP sockets
1087 */ 977 */
@@ -1367,6 +1257,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
1367 case 0: 1257 case 0:
1368 case UDP_ENCAP_ESPINUDP: 1258 case UDP_ENCAP_ESPINUDP:
1369 case UDP_ENCAP_ESPINUDP_NON_IKE: 1259 case UDP_ENCAP_ESPINUDP_NON_IKE:
1260 up->encap_rcv = xfrm4_udp_encap_rcv;
1261 /* FALLTHROUGH */
1370 case UDP_ENCAP_L2TPINUDP: 1262 case UDP_ENCAP_L2TPINUDP:
1371 up->encap_type = val; 1263 up->encap_type = val;
1372 break; 1264 break;
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index fa1902dc81b8..2fa108245413 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -16,13 +16,6 @@
16#include <net/ip.h> 16#include <net/ip.h>
17#include <net/xfrm.h> 17#include <net/xfrm.h>
18 18
19int xfrm4_rcv(struct sk_buff *skb)
20{
21 return xfrm4_rcv_encap(skb, 0);
22}
23
24EXPORT_SYMBOL(xfrm4_rcv);
25
26static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq) 19static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
27{ 20{
28 switch (nexthdr) { 21 switch (nexthdr) {
@@ -53,7 +46,7 @@ drop:
53} 46}
54#endif 47#endif
55 48
56int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) 49static int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
57{ 50{
58 __be32 spi, seq; 51 __be32 spi, seq;
59 struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH]; 52 struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
@@ -167,3 +160,108 @@ drop:
167 kfree_skb(skb); 160 kfree_skb(skb);
168 return 0; 161 return 0;
169} 162}
163
164/* If it's a keepalive packet, then just eat it.
165 * If it's an encapsulated packet, then pass it to the
166 * IPsec xfrm input.
167 * Returns 0 if skb passed to xfrm or was dropped.
168 * Returns >0 if skb should be passed to UDP.
169 * Returns <0 if skb should be resubmitted (-ret is protocol)
170 */
171int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
172{
173 struct udp_sock *up = udp_sk(sk);
174 struct udphdr *uh;
175 struct iphdr *iph;
176 int iphlen, len;
177 int ret;
178
179 __u8 *udpdata;
180 __be32 *udpdata32;
181 __u16 encap_type = up->encap_type;
182
183 /* if this is not encapsulated socket, then just return now */
184 if (!encap_type)
185 return 1;
186
187 /* If this is a paged skb, make sure we pull up
188 * whatever data we need to look at. */
189 len = skb->len - sizeof(struct udphdr);
190 if (!pskb_may_pull(skb, sizeof(struct udphdr) + min(len, 8)))
191 return 1;
192
193 /* Now we can get the pointers */
194 uh = udp_hdr(skb);
195 udpdata = (__u8 *)uh + sizeof(struct udphdr);
196 udpdata32 = (__be32 *)udpdata;
197
198 switch (encap_type) {
199 default:
200 case UDP_ENCAP_ESPINUDP:
201 /* Check if this is a keepalive packet. If so, eat it. */
202 if (len == 1 && udpdata[0] == 0xff) {
203 goto drop;
204 } else if (len > sizeof(struct ip_esp_hdr) && udpdata32[0] != 0) {
205 /* ESP Packet without Non-ESP header */
206 len = sizeof(struct udphdr);
207 } else
208 /* Must be an IKE packet.. pass it through */
209 return 1;
210 break;
211 case UDP_ENCAP_ESPINUDP_NON_IKE:
212 /* Check if this is a keepalive packet. If so, eat it. */
213 if (len == 1 && udpdata[0] == 0xff) {
214 goto drop;
215 } else if (len > 2 * sizeof(u32) + sizeof(struct ip_esp_hdr) &&
216 udpdata32[0] == 0 && udpdata32[1] == 0) {
217
218 /* ESP Packet with Non-IKE marker */
219 len = sizeof(struct udphdr) + 2 * sizeof(u32);
220 } else
221 /* Must be an IKE packet.. pass it through */
222 return 1;
223 break;
224 }
225
226 /* At this point we are sure that this is an ESPinUDP packet,
227 * so we need to remove 'len' bytes from the packet (the UDP
228 * header and optional ESP marker bytes) and then modify the
229 * protocol to ESP, and then call into the transform receiver.
230 */
231 if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
232 goto drop;
233
234 /* Now we can update and verify the packet length... */
235 iph = ip_hdr(skb);
236 iphlen = iph->ihl << 2;
237 iph->tot_len = htons(ntohs(iph->tot_len) - len);
238 if (skb->len < iphlen + len) {
239 /* packet is too small!?! */
240 goto drop;
241 }
242
243 /* pull the data buffer up to the ESP header and set the
244 * transport header to point to ESP. Keep UDP on the stack
245 * for later.
246 */
247 __skb_pull(skb, len);
248 skb_reset_transport_header(skb);
249
250 /* modify the protocol (it's ESP!) */
251 iph->protocol = IPPROTO_ESP;
252
253 /* process ESP */
254 ret = xfrm4_rcv_encap(skb, encap_type);
255 return ret;
256
257drop:
258 kfree_skb(skb);
259 return 0;
260}
261
262int xfrm4_rcv(struct sk_buff *skb)
263{
264 return xfrm4_rcv_encap(skb, 0);
265}
266
267EXPORT_SYMBOL(xfrm4_rcv);