aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/udp.h6
-rw-r--r--net/ipv4/udp.c27
2 files changed, 29 insertions, 4 deletions
diff --git a/include/linux/udp.h b/include/linux/udp.h
index 6de445c31a64..8ec703f462da 100644
--- a/include/linux/udp.h
+++ b/include/linux/udp.h
@@ -42,6 +42,7 @@ static inline struct udphdr *udp_hdr(const struct sk_buff *skb)
42/* UDP encapsulation types */ 42/* UDP encapsulation types */
43#define UDP_ENCAP_ESPINUDP_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */ 43#define UDP_ENCAP_ESPINUDP_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
44#define UDP_ENCAP_ESPINUDP 2 /* draft-ietf-ipsec-udp-encaps-06 */ 44#define UDP_ENCAP_ESPINUDP 2 /* draft-ietf-ipsec-udp-encaps-06 */
45#define UDP_ENCAP_L2TPINUDP 3 /* rfc2661 */
45 46
46#ifdef __KERNEL__ 47#ifdef __KERNEL__
47#include <linux/types.h> 48#include <linux/types.h>
@@ -70,6 +71,11 @@ struct udp_sock {
70#define UDPLITE_SEND_CC 0x2 /* set via udplite setsockopt */ 71#define UDPLITE_SEND_CC 0x2 /* set via udplite setsockopt */
71#define UDPLITE_RECV_CC 0x4 /* set via udplite setsocktopt */ 72#define UDPLITE_RECV_CC 0x4 /* set via udplite setsocktopt */
72 __u8 pcflag; /* marks socket as UDP-Lite if > 0 */ 73 __u8 pcflag; /* marks socket as UDP-Lite if > 0 */
74 __u8 unused[3];
75 /*
76 * For encapsulation sockets.
77 */
78 int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
73}; 79};
74 80
75static inline struct udp_sock *udp_sk(const struct sock *sk) 81static inline struct udp_sock *udp_sk(const struct sock *sk)
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index facb7e29304e..b9276f8bdac5 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -70,6 +70,7 @@
70 * Alexey Kuznetsov: allow both IPv4 and IPv6 sockets to bind 70 * Alexey Kuznetsov: allow both IPv4 and IPv6 sockets to bind
71 * a single port at the same time. 71 * a single port at the same time.
72 * Derek Atkins <derek@ihtfp.com>: Add Encapulation Support 72 * Derek Atkins <derek@ihtfp.com>: Add Encapulation Support
73 * James Chapman : Add L2TP encapsulation type.
73 * 74 *
74 * 75 *
75 * This program is free software; you can redistribute it and/or 76 * This program is free software; you can redistribute it and/or
@@ -923,12 +924,10 @@ int udp_disconnect(struct sock *sk, int flags)
923 * 1 if the UDP system should process it 924 * 1 if the UDP system should process it
924 * 0 if we should drop this packet 925 * 0 if we should drop this packet
925 * -1 if it should get processed by xfrm4_rcv_encap 926 * -1 if it should get processed by xfrm4_rcv_encap
927 * -2 if it should get processed by l2tp
926 */ 928 */
927static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb) 929static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
928{ 930{
929#ifndef CONFIG_XFRM
930 return 1;
931#else
932 struct udp_sock *up = udp_sk(sk); 931 struct udp_sock *up = udp_sk(sk);
933 struct udphdr *uh; 932 struct udphdr *uh;
934 struct iphdr *iph; 933 struct iphdr *iph;
@@ -983,8 +982,14 @@ static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
983 /* Must be an IKE packet.. pass it through */ 982 /* Must be an IKE packet.. pass it through */
984 return 1; 983 return 1;
985 break; 984 break;
985 case UDP_ENCAP_L2TPINUDP:
986 /* Let caller know to send this to l2tp */
987 return -2;
986 } 988 }
987 989
990#ifndef CONFIG_XFRM
991 return 1;
992#else
988 /* At this point we are sure that this is an ESPinUDP packet, 993 /* At this point we are sure that this is an ESPinUDP packet,
989 * so we need to remove 'len' bytes from the packet (the UDP 994 * so we need to remove 'len' bytes from the packet (the UDP
990 * header and optional ESP marker bytes) and then modify the 995 * header and optional ESP marker bytes) and then modify the
@@ -1055,12 +1060,25 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
1055 kfree_skb(skb); 1060 kfree_skb(skb);
1056 return 0; 1061 return 0;
1057 } 1062 }
1058 if (ret < 0) { 1063 if (ret == -1) {
1059 /* process the ESP packet */ 1064 /* process the ESP packet */
1060 ret = xfrm4_rcv_encap(skb, up->encap_type); 1065 ret = xfrm4_rcv_encap(skb, up->encap_type);
1061 UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag); 1066 UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag);
1062 return -ret; 1067 return -ret;
1063 } 1068 }
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 }
1080 }
1081
1064 /* FALLTHROUGH -- it's a UDP Packet */ 1082 /* FALLTHROUGH -- it's a UDP Packet */
1065 } 1083 }
1066 1084
@@ -1349,6 +1367,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
1349 case 0: 1367 case 0:
1350 case UDP_ENCAP_ESPINUDP: 1368 case UDP_ENCAP_ESPINUDP:
1351 case UDP_ENCAP_ESPINUDP_NON_IKE: 1369 case UDP_ENCAP_ESPINUDP_NON_IKE:
1370 case UDP_ENCAP_L2TPINUDP:
1352 up->encap_type = val; 1371 up->encap_type = val;
1353 break; 1372 break;
1354 default: 1373 default: