Skip to content

Commit 342f023

Browse files
j-c-hDavid S. Miller
authored andcommitted
[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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 4417da6 commit 342f023

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

include/linux/udp.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ static inline struct udphdr *udp_hdr(const struct sk_buff *skb)
4242
/* UDP encapsulation types */
4343
#define UDP_ENCAP_ESPINUDP_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
4444
#define UDP_ENCAP_ESPINUDP 2 /* draft-ietf-ipsec-udp-encaps-06 */
45+
#define UDP_ENCAP_L2TPINUDP 3 /* rfc2661 */
4546

4647
#ifdef __KERNEL__
4748
#include <linux/types.h>
@@ -70,6 +71,11 @@ struct udp_sock {
7071
#define UDPLITE_SEND_CC 0x2 /* set via udplite setsockopt */
7172
#define UDPLITE_RECV_CC 0x4 /* set via udplite setsocktopt */
7273
__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);
7379
};
7480

7581
static inline struct udp_sock *udp_sk(const struct sock *sk)

net/ipv4/udp.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
* Alexey Kuznetsov: allow both IPv4 and IPv6 sockets to bind
7171
* a single port at the same time.
7272
* Derek Atkins <[email protected]>: Add Encapulation Support
73+
* James Chapman : Add L2TP encapsulation type.
7374
*
7475
*
7576
* This program is free software; you can redistribute it and/or
@@ -923,12 +924,10 @@ int udp_disconnect(struct sock *sk, int flags)
923924
* 1 if the UDP system should process it
924925
* 0 if we should drop this packet
925926
* -1 if it should get processed by xfrm4_rcv_encap
927+
* -2 if it should get processed by l2tp
926928
*/
927929
static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
928930
{
929-
#ifndef CONFIG_XFRM
930-
return 1;
931-
#else
932931
struct udp_sock *up = udp_sk(sk);
933932
struct udphdr *uh;
934933
struct iphdr *iph;
@@ -983,8 +982,14 @@ static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
983982
/* Must be an IKE packet.. pass it through */
984983
return 1;
985984
break;
985+
case UDP_ENCAP_L2TPINUDP:
986+
/* Let caller know to send this to l2tp */
987+
return -2;
986988
}
987989

990+
#ifndef CONFIG_XFRM
991+
return 1;
992+
#else
988993
/* At this point we are sure that this is an ESPinUDP packet,
989994
* so we need to remove 'len' bytes from the packet (the UDP
990995
* 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)
10551060
kfree_skb(skb);
10561061
return 0;
10571062
}
1058-
if (ret < 0) {
1063+
if (ret == -1) {
10591064
/* process the ESP packet */
10601065
ret = xfrm4_rcv_encap(skb, up->encap_type);
10611066
UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag);
10621067
return -ret;
10631068
}
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+
10641082
/* FALLTHROUGH -- it's a UDP Packet */
10651083
}
10661084

@@ -1349,6 +1367,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
13491367
case 0:
13501368
case UDP_ENCAP_ESPINUDP:
13511369
case UDP_ENCAP_ESPINUDP_NON_IKE:
1370+
case UDP_ENCAP_L2TPINUDP:
13521371
up->encap_type = val;
13531372
break;
13541373
default:

0 commit comments

Comments
 (0)