Commit 0146dca7 authored by Sabrina Dubroca's avatar Sabrina Dubroca Committed by Steffen Klassert
Browse files

xfrm: add support for UDPv6 encapsulation of ESP



This patch adds support for encapsulation of ESP over UDPv6. The code
is very similar to the IPv4 encapsulation implementation, and allows
to easily add espintcp on IPv6 as a follow-up.

Signed-off-by: default avatarSabrina Dubroca <sd@queasysnail.net>
Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
parent e62905ae
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -56,6 +56,9 @@ struct ipv6_stub {
	void (*ndisc_send_na)(struct net_device *dev, const struct in6_addr *daddr,
	void (*ndisc_send_na)(struct net_device *dev, const struct in6_addr *daddr,
			      const struct in6_addr *solicited_addr,
			      const struct in6_addr *solicited_addr,
			      bool router, bool solicited, bool override, bool inc_opt);
			      bool router, bool solicited, bool override, bool inc_opt);
#if IS_ENABLED(CONFIG_XFRM)
	int (*xfrm6_udp_encap_rcv)(struct sock *sk, struct sk_buff *skb);
#endif
	struct neigh_table *nd_tbl;
	struct neigh_table *nd_tbl;
};
};
extern const struct ipv6_stub *ipv6_stub __read_mostly;
extern const struct ipv6_stub *ipv6_stub __read_mostly;
+5 −0
Original line number Original line Diff line number Diff line
@@ -1406,6 +1406,8 @@ struct xfrm4_protocol {


struct xfrm6_protocol {
struct xfrm6_protocol {
	int (*handler)(struct sk_buff *skb);
	int (*handler)(struct sk_buff *skb);
	int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi,
			     int encap_type);
	int (*cb_handler)(struct sk_buff *skb, int err);
	int (*cb_handler)(struct sk_buff *skb, int err);
	int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
	int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
			   u8 type, u8 code, int offset, __be32 info);
			   u8 type, u8 code, int offset, __be32 info);
@@ -1590,6 +1592,8 @@ int xfrm6_extract_header(struct sk_buff *skb);
int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
		  struct ip6_tnl *t);
		  struct ip6_tnl *t);
int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
		    int encap_type);
int xfrm6_transport_finish(struct sk_buff *skb, int async);
int xfrm6_transport_finish(struct sk_buff *skb, int async);
int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t);
int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t);
int xfrm6_rcv(struct sk_buff *skb);
int xfrm6_rcv(struct sk_buff *skb);
@@ -1610,6 +1614,7 @@ int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,


#ifdef CONFIG_XFRM
#ifdef CONFIG_XFRM
int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
int xfrm_user_policy(struct sock *sk, int optname,
int xfrm_user_policy(struct sock *sk, int optname,
		     u8 __user *optval, int optlen);
		     u8 __user *optval, int optlen);
#else
#else
+9 −1
Original line number Original line Diff line number Diff line
@@ -112,6 +112,9 @@
#include <net/sock_reuseport.h>
#include <net/sock_reuseport.h>
#include <net/addrconf.h>
#include <net/addrconf.h>
#include <net/udp_tunnel.h>
#include <net/udp_tunnel.h>
#if IS_ENABLED(CONFIG_IPV6)
#include <net/ipv6_stubs.h>
#endif


struct udp_table udp_table __read_mostly;
struct udp_table udp_table __read_mostly;
EXPORT_SYMBOL(udp_table);
EXPORT_SYMBOL(udp_table);
@@ -2563,6 +2566,11 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
#ifdef CONFIG_XFRM
#ifdef CONFIG_XFRM
		case UDP_ENCAP_ESPINUDP:
		case UDP_ENCAP_ESPINUDP:
		case UDP_ENCAP_ESPINUDP_NON_IKE:
		case UDP_ENCAP_ESPINUDP_NON_IKE:
#if IS_ENABLED(CONFIG_IPV6)
			if (sk->sk_family == AF_INET6)
				up->encap_rcv = ipv6_stub->xfrm6_udp_encap_rcv;
			else
#endif
				up->encap_rcv = xfrm4_udp_encap_rcv;
				up->encap_rcv = xfrm4_udp_encap_rcv;
#endif
#endif
			fallthrough;
			fallthrough;
+4 −0
Original line number Original line Diff line number Diff line
@@ -60,6 +60,7 @@
#include <net/calipso.h>
#include <net/calipso.h>
#include <net/seg6.h>
#include <net/seg6.h>
#include <net/rpl.h>
#include <net/rpl.h>
#include <net/xfrm.h>


#include <linux/uaccess.h>
#include <linux/uaccess.h>
#include <linux/mroute6.h>
#include <linux/mroute6.h>
@@ -961,6 +962,9 @@ static const struct ipv6_stub ipv6_stub_impl = {
	.ip6_del_rt	   = ip6_del_rt,
	.ip6_del_rt	   = ip6_del_rt,
	.udpv6_encap_enable = udpv6_encap_enable,
	.udpv6_encap_enable = udpv6_encap_enable,
	.ndisc_send_na = ndisc_send_na,
	.ndisc_send_na = ndisc_send_na,
#if IS_ENABLED(CONFIG_XFRM)
	.xfrm6_udp_encap_rcv = xfrm6_udp_encap_rcv,
#endif
	.nd_tbl	= &nd_tbl,
	.nd_tbl	= &nd_tbl,
};
};


+1 −0
Original line number Original line Diff line number Diff line
@@ -767,6 +767,7 @@ static const struct xfrm_type ah6_type = {


static struct xfrm6_protocol ah6_protocol = {
static struct xfrm6_protocol ah6_protocol = {
	.handler	=	xfrm6_rcv,
	.handler	=	xfrm6_rcv,
	.input_handler	=	xfrm_input,
	.cb_handler	=	ah6_rcv_cb,
	.cb_handler	=	ah6_rcv_cb,
	.err_handler	=	ah6_err,
	.err_handler	=	ah6_err,
	.priority	=	0,
	.priority	=	0,
Loading