mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-09 15:29:16 +00:00
[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>
This commit is contained in:
parent
4417da668c
commit
342f0234c7
@ -42,6 +42,7 @@ static inline struct udphdr *udp_hdr(const struct sk_buff *skb)
|
|||||||
/* UDP encapsulation types */
|
/* UDP encapsulation types */
|
||||||
#define UDP_ENCAP_ESPINUDP_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
|
#define UDP_ENCAP_ESPINUDP_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
|
||||||
#define UDP_ENCAP_ESPINUDP 2 /* draft-ietf-ipsec-udp-encaps-06 */
|
#define UDP_ENCAP_ESPINUDP 2 /* draft-ietf-ipsec-udp-encaps-06 */
|
||||||
|
#define UDP_ENCAP_L2TPINUDP 3 /* rfc2661 */
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
@ -70,6 +71,11 @@ struct udp_sock {
|
|||||||
#define UDPLITE_SEND_CC 0x2 /* set via udplite setsockopt */
|
#define UDPLITE_SEND_CC 0x2 /* set via udplite setsockopt */
|
||||||
#define UDPLITE_RECV_CC 0x4 /* set via udplite setsocktopt */
|
#define UDPLITE_RECV_CC 0x4 /* set via udplite setsocktopt */
|
||||||
__u8 pcflag; /* marks socket as UDP-Lite if > 0 */
|
__u8 pcflag; /* marks socket as UDP-Lite if > 0 */
|
||||||
|
__u8 unused[3];
|
||||||
|
/*
|
||||||
|
* For encapsulation sockets.
|
||||||
|
*/
|
||||||
|
int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct udp_sock *udp_sk(const struct sock *sk)
|
static inline struct udp_sock *udp_sk(const struct sock *sk)
|
||||||
|
@ -70,6 +70,7 @@
|
|||||||
* Alexey Kuznetsov: allow both IPv4 and IPv6 sockets to bind
|
* Alexey Kuznetsov: allow both IPv4 and IPv6 sockets to bind
|
||||||
* a single port at the same time.
|
* a single port at the same time.
|
||||||
* Derek Atkins <derek@ihtfp.com>: Add Encapulation Support
|
* Derek Atkins <derek@ihtfp.com>: Add Encapulation Support
|
||||||
|
* James Chapman : Add L2TP encapsulation type.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
@ -923,12 +924,10 @@ int udp_disconnect(struct sock *sk, int flags)
|
|||||||
* 1 if the UDP system should process it
|
* 1 if the UDP system should process it
|
||||||
* 0 if we should drop this packet
|
* 0 if we should drop this packet
|
||||||
* -1 if it should get processed by xfrm4_rcv_encap
|
* -1 if it should get processed by xfrm4_rcv_encap
|
||||||
|
* -2 if it should get processed by l2tp
|
||||||
*/
|
*/
|
||||||
static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
|
static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
#ifndef CONFIG_XFRM
|
|
||||||
return 1;
|
|
||||||
#else
|
|
||||||
struct udp_sock *up = udp_sk(sk);
|
struct udp_sock *up = udp_sk(sk);
|
||||||
struct udphdr *uh;
|
struct udphdr *uh;
|
||||||
struct iphdr *iph;
|
struct iphdr *iph;
|
||||||
@ -983,8 +982,14 @@ static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
|
|||||||
/* Must be an IKE packet.. pass it through */
|
/* Must be an IKE packet.. pass it through */
|
||||||
return 1;
|
return 1;
|
||||||
break;
|
break;
|
||||||
|
case UDP_ENCAP_L2TPINUDP:
|
||||||
|
/* Let caller know to send this to l2tp */
|
||||||
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_XFRM
|
||||||
|
return 1;
|
||||||
|
#else
|
||||||
/* At this point we are sure that this is an ESPinUDP packet,
|
/* At this point we are sure that this is an ESPinUDP packet,
|
||||||
* so we need to remove 'len' bytes from the packet (the UDP
|
* so we need to remove 'len' bytes from the packet (the UDP
|
||||||
* header and optional ESP marker bytes) and then modify the
|
* 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)
|
|||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (ret < 0) {
|
if (ret == -1) {
|
||||||
/* process the ESP packet */
|
/* process the ESP packet */
|
||||||
ret = xfrm4_rcv_encap(skb, up->encap_type);
|
ret = xfrm4_rcv_encap(skb, up->encap_type);
|
||||||
UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag);
|
UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag);
|
||||||
return -ret;
|
return -ret;
|
||||||
}
|
}
|
||||||
|
if (ret == -2) {
|
||||||
|
/* process the L2TP packet */
|
||||||
|
if (up->encap_rcv != NULL) {
|
||||||
|
ret = (*up->encap_rcv)(sk, skb);
|
||||||
|
if (ret <= 0) {
|
||||||
|
UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FALLTHROUGH -- pass up as UDP packet */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* FALLTHROUGH -- it's a UDP Packet */
|
/* FALLTHROUGH -- it's a UDP Packet */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1349,6 +1367,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
|
|||||||
case 0:
|
case 0:
|
||||||
case UDP_ENCAP_ESPINUDP:
|
case UDP_ENCAP_ESPINUDP:
|
||||||
case UDP_ENCAP_ESPINUDP_NON_IKE:
|
case UDP_ENCAP_ESPINUDP_NON_IKE:
|
||||||
|
case UDP_ENCAP_L2TPINUDP:
|
||||||
up->encap_type = val;
|
up->encap_type = val;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user