Skip to content

Commit

Permalink
xfrm: Add virtual xfrm interfaces
Browse files Browse the repository at this point in the history
This patch adds support for virtual xfrm interfaces.
Packets that are routed through such an interface
are guaranteed to be IPsec transformed or dropped.
It is a generic virtual interface that ensures IPsec
transformation, no need to know what happens behind
the interface. This means that we can tunnel IPv4 and
IPv6 through the same interface and support all xfrm
modes (tunnel, transport and beet) on it.

Co-developed-by: Lorenzo Colitti <lorenzo@google.com>
Co-developed-by: Benedict Wong <benedictwong@google.com>
Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
Signed-off-by: Benedict Wong <benedictwong@google.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Acked-by: Shannon Nelson <shannon.nelson@oracle.com>
Tested-by: Benedict Wong <benedictwong@google.com>
Tested-by: Antony Antony <antony@phenome.org>
Reviewed-by: Eyal Birger <eyal.birger@gmail.com>
  • Loading branch information
klassert committed Jun 23, 2018
1 parent 7e65264 commit f203b76
Show file tree
Hide file tree
Showing 7 changed files with 1,061 additions and 0 deletions.
24 changes: 24 additions & 0 deletions include/net/xfrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <net/ipv6.h>
#include <net/ip6_fib.h>
#include <net/flow.h>
#include <net/gro_cells.h>

#include <linux/interrupt.h>

Expand Down Expand Up @@ -293,6 +294,13 @@ struct xfrm_replay {
int (*overflow)(struct xfrm_state *x, struct sk_buff *skb);
};

struct xfrm_if_cb {
struct xfrm_if *(*decode_session)(struct sk_buff *skb);
};

void xfrm_if_register_cb(const struct xfrm_if_cb *ifcb);
void xfrm_if_unregister_cb(void);

struct net_device;
struct xfrm_type;
struct xfrm_dst;
Expand Down Expand Up @@ -1039,6 +1047,22 @@ static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)

void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);

struct xfrm_if_parms {
char name[IFNAMSIZ]; /* name of XFRM device */
int link; /* ifindex of underlying L2 interface */
u32 if_id; /* interface identifyer */
};

struct xfrm_if {
struct xfrm_if __rcu *next; /* next interface in list */
struct net_device *dev; /* virtual device associated with interface */
struct net_device *phydev; /* physical device */
struct net *net; /* netns for packet i/o */
struct xfrm_if_parms p; /* interface parms */

struct gro_cells gro_cells;
};

struct xfrm_offload {
/* Output sequence number for replay protection on offloading. */
struct {
Expand Down
10 changes: 10 additions & 0 deletions include/uapi/linux/if_link.h
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,16 @@ enum {

#define IFLA_MACSEC_MAX (__IFLA_MACSEC_MAX - 1)

/* XFRM section */
enum {
IFLA_XFRM_UNSPEC,
IFLA_XFRM_LINK,
IFLA_XFRM_IF_ID,
__IFLA_XFRM_MAX
};

#define IFLA_XFRM_MAX (__IFLA_XFRM_MAX - 1)

enum macsec_validation_type {
MACSEC_VALIDATE_DISABLED = 0,
MACSEC_VALIDATE_CHECK = 1,
Expand Down
8 changes: 8 additions & 0 deletions net/xfrm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ config XFRM_USER

If unsure, say Y.

config XFRM_INTERFACE
tristate "Transformation virtual interface"
depends on XFRM && IPV6
---help---
This provides a virtual interface to route IPsec traffic.

If unsure, say N.

config XFRM_SUB_POLICY
bool "Transformation sub policy support"
depends on XFRM
Expand Down
1 change: 1 addition & 0 deletions net/xfrm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ obj-$(CONFIG_XFRM_STATISTICS) += xfrm_proc.o
obj-$(CONFIG_XFRM_ALGO) += xfrm_algo.o
obj-$(CONFIG_XFRM_USER) += xfrm_user.o
obj-$(CONFIG_XFRM_IPCOMP) += xfrm_ipcomp.o
obj-$(CONFIG_XFRM_INTERFACE) += xfrm_interface.o
3 changes: 3 additions & 0 deletions net/xfrm/xfrm_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)

seq = 0;
if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) {
secpath_reset(skb);
XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
goto drop;
}
Expand All @@ -328,12 +329,14 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
XFRM_SPI_SKB_CB(skb)->daddroff);
do {
if (skb->sp->len == XFRM_MAX_DEPTH) {
secpath_reset(skb);
XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR);
goto drop;
}

x = xfrm_state_lookup(net, mark, daddr, spi, nexthdr, family);
if (x == NULL) {
secpath_reset(skb);
XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES);
xfrm_audit_state_notfound(skb, family, spi, seq);
goto drop;
Expand Down
Loading

0 comments on commit f203b76

Please sign in to comment.