Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7a49d3d4 authored by David S. Miller's avatar David S. Miller
Browse files


Steffen Klassert says:

====================
pull request (net-next): ipsec-next 2018-07-27

1) Extend the output_mark to also support the input direction
   and masking the mark values before applying to the skb.

2) Add a new lookup key for the upcomming xfrm interfaces.

3) Extend the xfrm lookups to match xfrm interface IDs.

4) Add virtual xfrm interfaces. The purpose of these interfaces
   is to overcome the design limitations that the existing
   VTI devices have.

  The main limitations that we see with the current VTI are the
  following:

  VTI interfaces are L3 tunnels with configurable endpoints.
  For xfrm, the tunnel endpoint are already determined by the SA.
  So the VTI tunnel endpoints must be either the same as on the
  SA or wildcards. In case VTI tunnel endpoints are same as on
  the SA, we get a one to one correlation between the SA and
  the tunnel. So each SA needs its own tunnel interface.

  On the other hand, we can have only one VTI tunnel with
  wildcard src/dst tunnel endpoints in the system because the
  lookup is based on the tunnel endpoints. The existing tunnel
  lookup won't work with multiple tunnels with wildcard
  tunnel endpoints. Some usecases require more than on
  VTI tunnel of this type, for example if somebody has multiple
  namespaces and every namespace requires such a VTI.

  VTI needs separate interfaces for IPv4 and IPv6 tunnels.
  So when routing to a VTI, we have to know to which address
  family this traffic class is going to be encapsulated.
  This is a lmitation because it makes routing more complex
  and it is not always possible to know what happens behind the
  VTI, e.g. when the VTI is move to some namespace.

  VTI works just with tunnel mode SAs. We need generic interfaces
  that ensures transfomation, regardless of the xfrm mode and
  the encapsulated address family.

  VTI is configured with a combination GRE keys and xfrm marks.
  With this we have to deal with some extra cases in the generic
  tunnel lookup because the GRE keys on the VTI are actually
  not GRE keys, the GRE keys were just reused for something else.
  All extensions to the VTI interfaces would require to add
  even more complexity to the generic tunnel lookup.

  So to overcome this, we developed xfrm interfaces with the
  following design goal:

  It should be possible to tunnel IPv4 and IPv6 through the same
  interface.

  No limitation on xfrm mode (tunnel, transport and beet).

  Should be a generic virtual interface that ensures IPsec
  transformation, no need to know what happens behind the
  interface.

  Interfaces should be configured with a new key that must match a
  new policy/SA lookup key.

  The lookup logic should stay in the xfrm codebase, no need to
  change or extend generic routing and tunnel lookups.

  Should be possible to use IPsec hardware offloads of the underlying
  interface.

5) Remove xfrm pcpu policy cache. This was added after the flowcache
   removal, but it turned out to make things even worse.
   From Florian Westphal.

6) Allow to update the set mark on SA updates.
   From Nathan Harold.

7) Convert some timestamps to time64_t.
   From Arnd Bergmann.

8) Don't check the offload_handle in xfrm code,
   it is an opaque data cookie for the driver.
   From Shannon Nelson.

9) Remove xfrmi interface ID from flowi. After this pach
   no generic code is touched anymore to do xfrm interface
   lookups. From Benedict Wong.

10) Allow to update the xfrm interface ID on SA updates.
    From Nathan Harold.

11) Don't pass zero to ERR_PTR() in xfrm_resolve_and_create_bundle.
    From YueHaibing.

12) Return more detailed errors on xfrm interface creation.
    From Benedict Wong.

13) Use PTR_ERR_OR_ZERO instead of IS_ERR + PTR_ERR.
    From the kbuild test robot.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ecbcd689 c6f5e017
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -475,6 +475,14 @@ static inline struct dst_entry *xfrm_lookup(struct net *net,
	return dst_orig;
}

static inline struct dst_entry *
xfrm_lookup_with_ifid(struct net *net, struct dst_entry *dst_orig,
		      const struct flowi *fl, const struct sock *sk,
		      int flags, u32 if_id)
{
	return dst_orig;
}

static inline struct dst_entry *xfrm_lookup_route(struct net *net,
						  struct dst_entry *dst_orig,
						  const struct flowi *fl,
@@ -494,6 +502,12 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig,
			      const struct flowi *fl, const struct sock *sk,
			      int flags);

struct dst_entry *xfrm_lookup_with_ifid(struct net *net,
					struct dst_entry *dst_orig,
					const struct flowi *fl,
					const struct sock *sk, int flags,
					u32 if_id);

struct dst_entry *xfrm_lookup_route(struct net *net, struct dst_entry *dst_orig,
				    const struct flowi *fl, const struct sock *sk,
				    int flags);
+50 −9
Original line number Diff line number Diff line
@@ -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>

@@ -147,6 +148,7 @@ struct xfrm_state {
	struct xfrm_id		id;
	struct xfrm_selector	sel;
	struct xfrm_mark	mark;
	u32			if_id;
	u32			tfcpad;

	u32			genid;
@@ -166,7 +168,7 @@ struct xfrm_state {
		int		header_len;
		int		trailer_len;
		u32		extra_flags;
		u32		output_mark;
		struct xfrm_mark	smark;
	} props;

	struct xfrm_lifetime_cfg lft;
@@ -225,7 +227,7 @@ struct xfrm_state {
	long		saved_tmo;

	/* Last used time */
	unsigned long		lastused;
	time64_t		lastused;

	struct page_frag xfrag;

@@ -292,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;
@@ -323,7 +332,6 @@ int xfrm_policy_register_afinfo(const struct xfrm_policy_afinfo *afinfo, int fam
void xfrm_policy_unregister_afinfo(const struct xfrm_policy_afinfo *afinfo);
void km_policy_notify(struct xfrm_policy *xp, int dir,
		      const struct km_event *c);
void xfrm_policy_cache_flush(void);
void km_state_notify(struct xfrm_state *x, const struct km_event *c);

struct xfrm_tmpl;
@@ -574,6 +582,7 @@ struct xfrm_policy {
	atomic_t		genid;
	u32			priority;
	u32			index;
	u32			if_id;
	struct xfrm_mark	mark;
	struct xfrm_selector	selector;
	struct xfrm_lifetime_cfg lft;
@@ -1037,6 +1046,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 {
@@ -1532,8 +1557,8 @@ struct xfrm_state *xfrm_state_find(const xfrm_address_t *daddr,
				   const struct flowi *fl,
				   struct xfrm_tmpl *tmpl,
				   struct xfrm_policy *pol, int *err,
				   unsigned short family);
struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark,
				   unsigned short family, u32 if_id);
struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark, u32 if_id,
				       xfrm_address_t *daddr,
				       xfrm_address_t *saddr,
				       unsigned short family,
@@ -1690,20 +1715,20 @@ int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk,
		     void *);
void xfrm_policy_walk_done(struct xfrm_policy_walk *walk, struct net *net);
int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark,
struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u32 if_id,
					  u8 type, int dir,
					  struct xfrm_selector *sel,
					  struct xfrm_sec_ctx *ctx, int delete,
					  int *err);
struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8, int dir,
				     u32 id, int delete, int *err);
struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u32 if_id, u8,
				     int dir, u32 id, int delete, int *err);
int xfrm_policy_flush(struct net *net, u8 type, bool task_valid);
void xfrm_policy_hash_rebuild(struct net *net);
u32 xfrm_get_acqseq(void);
int verify_spi_info(u8 proto, u32 min, u32 max);
int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
struct xfrm_state *xfrm_find_acq(struct net *net, const struct xfrm_mark *mark,
				 u8 mode, u32 reqid, u8 proto,
				 u8 mode, u32 reqid, u32 if_id, u8 proto,
				 const xfrm_address_t *daddr,
				 const xfrm_address_t *saddr, int create,
				 unsigned short family);
@@ -2012,6 +2037,22 @@ static inline int xfrm_mark_put(struct sk_buff *skb, const struct xfrm_mark *m)
	return ret;
}

static inline __u32 xfrm_smark_get(__u32 mark, struct xfrm_state *x)
{
	struct xfrm_mark *m = &x->props.smark;

	return (m->v & m->m) | (mark & ~m->m);
}

static inline int xfrm_if_id_put(struct sk_buff *skb, __u32 if_id)
{
	int ret = 0;

	if (if_id)
		ret = nla_put_u32(skb, XFRMA_IF_ID, if_id);
	return ret;
}

static inline int xfrm_tunnel_check(struct sk_buff *skb, struct xfrm_state *x,
				    unsigned int family)
{
+10 −0
Original line number Diff line number Diff line
@@ -460,6 +460,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,
+4 −1
Original line number Diff line number Diff line
@@ -305,9 +305,12 @@ enum xfrm_attr_type_t {
	XFRMA_ADDRESS_FILTER,	/* struct xfrm_address_filter */
	XFRMA_PAD,
	XFRMA_OFFLOAD_DEV,	/* struct xfrm_state_offload */
	XFRMA_OUTPUT_MARK,	/* __u32 */
	XFRMA_SET_MARK,		/* __u32 */
	XFRMA_SET_MARK_MASK,	/* __u32 */
	XFRMA_IF_ID,		/* __u32 */
	__XFRMA_MAX

#define XFRMA_OUTPUT_MARK XFRMA_SET_MARK	/* Compatibility */
#define XFRMA_MAX (__XFRMA_MAX - 1)
};

+1 −1
Original line number Diff line number Diff line
@@ -2253,7 +2253,7 @@ static void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow)
			x = xfrm_state_lookup_byspi(pn->net, htonl(pkt_dev->spi), AF_INET);
		} else {
			/* slow path: we dont already have xfrm_state */
			x = xfrm_stateonly_find(pn->net, DUMMY_MARK,
			x = xfrm_stateonly_find(pn->net, DUMMY_MARK, 0,
						(xfrm_address_t *)&pkt_dev->cur_daddr,
						(xfrm_address_t *)&pkt_dev->cur_saddr,
						AF_INET,
Loading