aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorJames Chapman <jchapman@katalix.com>2007-06-27 18:37:46 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-11 01:15:57 -0400
commit342f0234c71b40da785dd6a7ce1dd481ecbfdb81 (patch)
treeb6d7295cd484449f3f6478fe3e796fc8988534a3 /net/ipv4
parent4417da668c0021903464f92db278ddae348e0299 (diff)
[UDP]: Introduce UDP encapsulation type for L2TP
This patch adds a new UDP_ENCAP_L2TPINUDP encapsulation type for UDP sockets. When a UDP socket's encap_type is UDP_ENCAP_L2TPINUDP, the skb is delivered to a function pointed to by the udp_sock's encap_rcv funcptr. If the skb isn't wanted by L2TP, it returns >0, which causes it to be passed through to UDP. Include padding to put the new encap_rcv field on a 4-byte boundary. Previously, the only user of UDP encap sockets was ESP, so when CONFIG_XFRM was not defined, some of the encap code was compiled out. This patch changes that. As a result, udp_encap_rcv() will now do a little more work when CONFIG_XFRM is not defined. Signed-off-by: James Chapman <jchapman@katalix.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/udp.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index facb7e29304..b9276f8bdac 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: