Skip to content

Commit

Permalink
xfrm: add support for UDPv6 encapsulation of ESP
Browse files Browse the repository at this point in the history
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: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
  • Loading branch information
Sabrina Dubroca authored and Steffen Klassert committed Apr 28, 2020
1 parent e62905a commit 0146dca
Show file tree
Hide file tree
Showing 12 changed files with 395 additions and 37 deletions.
3 changes: 3 additions & 0 deletions include/net/ipv6_stubs.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ struct ipv6_stub {
void (*ndisc_send_na)(struct net_device *dev, const struct in6_addr *daddr,
const struct in6_addr *solicited_addr,
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;
};
extern const struct ipv6_stub *ipv6_stub __read_mostly;
Expand Down
5 changes: 5 additions & 0 deletions include/net/xfrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1406,6 +1406,8 @@ struct xfrm4_protocol {

struct xfrm6_protocol {
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 (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
u8 type, u8 code, int offset, __be32 info);
Expand Down Expand Up @@ -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_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
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_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t);
int xfrm6_rcv(struct sk_buff *skb);
Expand All @@ -1610,6 +1614,7 @@ int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,

#ifdef CONFIG_XFRM
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,
u8 __user *optval, int optlen);
#else
Expand Down
10 changes: 9 additions & 1 deletion net/ipv4/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@
#include <net/sock_reuseport.h>
#include <net/addrconf.h>
#include <net/udp_tunnel.h>
#if IS_ENABLED(CONFIG_IPV6)
#include <net/ipv6_stubs.h>
#endif

struct udp_table udp_table __read_mostly;
EXPORT_SYMBOL(udp_table);
Expand Down Expand Up @@ -2563,7 +2566,12 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
#ifdef CONFIG_XFRM
case UDP_ENCAP_ESPINUDP:
case UDP_ENCAP_ESPINUDP_NON_IKE:
up->encap_rcv = xfrm4_udp_encap_rcv;
#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;
#endif
fallthrough;
case UDP_ENCAP_L2TPINUDP:
Expand Down
4 changes: 4 additions & 0 deletions net/ipv6/af_inet6.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#include <net/calipso.h>
#include <net/seg6.h>
#include <net/rpl.h>
#include <net/xfrm.h>

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

Expand Down
1 change: 1 addition & 0 deletions net/ipv6/ah6.c
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,7 @@ static const struct xfrm_type ah6_type = {

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

0 comments on commit 0146dca

Please sign in to comment.