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

Commit 21c721fd authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'ovs-conntrack'

Joe Stringer says:

====================
OVS conntrack support

The goal of this series is to allow OVS to send packets through the Linux
kernel connection tracker, and subsequently match on fields populated by
conntrack. This functionality is enabled through a new
CONFIG_OPENVSWITCH_CONNTRACK option.

This version addresses the feedback from v5, primarily checking the behaviour
is correct with different configurations such as disabling
CONFIG_OPENVSWITCH_CONNTRACK or disabling individual conntrack features like
connlabels.

The branch below has been updated with the corresponding userspace pieces:
https://github.com/joestringer/ovs

 dev/ct_20150818
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 538e4563 cae3a262
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -289,13 +289,18 @@ static inline void skb_dst_drop(struct sk_buff *skb)
	}
}

static inline void skb_dst_copy(struct sk_buff *nskb, const struct sk_buff *oskb)
static inline void __skb_dst_copy(struct sk_buff *nskb, unsigned long refdst)
{
	nskb->_skb_refdst = oskb->_skb_refdst;
	nskb->_skb_refdst = refdst;
	if (!(nskb->_skb_refdst & SKB_DST_NOREF))
		dst_clone(skb_dst(nskb));
}

static inline void skb_dst_copy(struct sk_buff *nskb, const struct sk_buff *oskb)
{
	__skb_dst_copy(nskb, oskb->_skb_refdst);
}

/**
 * skb_dst_force - makes sure skb dst is refcounted
 * @skb: buffer
+4 −0
Original line number Diff line number Diff line
@@ -54,7 +54,11 @@ int nf_connlabels_replace(struct nf_conn *ct,
#ifdef CONFIG_NF_CONNTRACK_LABELS
int nf_conntrack_labels_init(void);
void nf_conntrack_labels_fini(void);
int nf_connlabels_get(struct net *net, unsigned int n_bits);
void nf_connlabels_put(struct net *net);
#else
static inline int nf_conntrack_labels_init(void) { return 0; }
static inline void nf_conntrack_labels_fini(void) {}
static inline int nf_connlabels_get(struct net *net, unsigned int n_bits) { return 0; }
static inline void nf_connlabels_put(struct net *net) {}
#endif
+58 −0
Original line number Diff line number Diff line
@@ -164,6 +164,9 @@ enum ovs_packet_cmd {
 * %OVS_USERSPACE_ATTR_EGRESS_TUN_PORT attribute, which is sent only if the
 * output port is actually a tunnel port. Contains the output tunnel key
 * extracted from the packet as nested %OVS_TUNNEL_KEY_ATTR_* attributes.
 * @OVS_PACKET_ATTR_MRU: Present for an %OVS_PACKET_CMD_ACTION and
 * %OVS_PACKET_ATTR_USERSPACE action specify the Maximum received fragment
 * size.
 *
 * These attributes follow the &struct ovs_header within the Generic Netlink
 * payload for %OVS_PACKET_* commands.
@@ -180,6 +183,7 @@ enum ovs_packet_attr {
	OVS_PACKET_ATTR_UNUSED2,
	OVS_PACKET_ATTR_PROBE,      /* Packet operation is a feature probe,
				       error logging should be suppressed. */
	OVS_PACKET_ATTR_MRU,	    /* Maximum received IP fragment size. */
	__OVS_PACKET_ATTR_MAX
};

@@ -319,6 +323,10 @@ enum ovs_key_attr {
	OVS_KEY_ATTR_MPLS,      /* array of struct ovs_key_mpls.
				 * The implementation may restrict
				 * the accepted length of the array. */
	OVS_KEY_ATTR_CT_STATE,	/* u8 bitmask of OVS_CS_F_* */
	OVS_KEY_ATTR_CT_ZONE,	/* u16 connection tracking zone. */
	OVS_KEY_ATTR_CT_MARK,	/* u32 connection tracking mark */
	OVS_KEY_ATTR_CT_LABEL,	/* 16-octet connection tracking label */

#ifdef __KERNEL__
	OVS_KEY_ATTR_TUNNEL_INFO,  /* struct ip_tunnel_info */
@@ -431,6 +439,20 @@ struct ovs_key_nd {
	__u8	nd_tll[ETH_ALEN];
};

#define OVS_CT_LABEL_LEN	16
struct ovs_key_ct_label {
	__u8	ct_label[OVS_CT_LABEL_LEN];
};

/* OVS_KEY_ATTR_CT_STATE flags */
#define OVS_CS_F_NEW               0x01 /* Beginning of a new connection. */
#define OVS_CS_F_ESTABLISHED       0x02 /* Part of an existing connection. */
#define OVS_CS_F_RELATED           0x04 /* Related to an established
					 * connection. */
#define OVS_CS_F_INVALID           0x20 /* Could not track connection. */
#define OVS_CS_F_REPLY_DIR         0x40 /* Flow is in the reply direction. */
#define OVS_CS_F_TRACKED           0x80 /* Conntrack has occurred. */

/**
 * enum ovs_flow_attr - attributes for %OVS_FLOW_* commands.
 * @OVS_FLOW_ATTR_KEY: Nested %OVS_KEY_ATTR_* attributes specifying the flow
@@ -594,6 +616,39 @@ struct ovs_action_hash {
	uint32_t  hash_basis;
};

/**
 * enum ovs_ct_attr - Attributes for %OVS_ACTION_ATTR_CT action.
 * @OVS_CT_ATTR_FLAGS: u32 connection tracking flags.
 * @OVS_CT_ATTR_ZONE: u16 connection tracking zone.
 * @OVS_CT_ATTR_MARK: u32 value followed by u32 mask. For each bit set in the
 * mask, the corresponding bit in the value is copied to the connection
 * tracking mark field in the connection.
 * @OVS_CT_ATTR_LABEL: %OVS_CT_LABEL_LEN value followed by %OVS_CT_LABEL_LEN
 * mask. For each bit set in the mask, the corresponding bit in the value is
 * copied to the connection tracking label field in the connection.
 * @OVS_CT_ATTR_HELPER: variable length string defining conntrack ALG.
 */
enum ovs_ct_attr {
	OVS_CT_ATTR_UNSPEC,
	OVS_CT_ATTR_FLAGS,      /* u8 bitmask of OVS_CT_F_*. */
	OVS_CT_ATTR_ZONE,       /* u16 zone id. */
	OVS_CT_ATTR_MARK,       /* mark to associate with this connection. */
	OVS_CT_ATTR_LABEL,      /* label to associate with this connection. */
	OVS_CT_ATTR_HELPER,     /* netlink helper to assist detection of
				   related connections. */
	__OVS_CT_ATTR_MAX
};

#define OVS_CT_ATTR_MAX (__OVS_CT_ATTR_MAX - 1)

/*
 * OVS_CT_ATTR_FLAGS flags - bitmask of %OVS_CT_F_*
 * @OVS_CT_F_COMMIT: Commits the flow to the conntrack table. This allows
 * future packets for the same connection to be identified as 'established'
 * or 'related'.
 */
#define OVS_CT_F_COMMIT		0x01

/**
 * enum ovs_action_attr - Action types.
 *
@@ -623,6 +678,8 @@ struct ovs_action_hash {
 * indicate the new packet contents. This could potentially still be
 * %ETH_P_MPLS if the resulting MPLS label stack is not empty.  If there
 * is no MPLS label stack, as determined by ethertype, no action is taken.
 * @OVS_ACTION_ATTR_CT: Track the connection. Populate the conntrack-related
 * entries in the flow key.
 *
 * Only a single header can be set with a single %OVS_ACTION_ATTR_SET.  Not all
 * fields within a header are modifiable, e.g. the IPv4 protocol and fragment
@@ -648,6 +705,7 @@ enum ovs_action_attr {
				       * data immediately followed by a mask.
				       * The data must be zero for the unmasked
				       * bits. */
	OVS_ACTION_ATTR_CT,           /* One nested OVS_CT_ATTR_* . */

	__OVS_ACTION_ATTR_MAX,	      /* Nothing past this will be accepted
				       * from userspace. */
+1 −0
Original line number Diff line number Diff line
@@ -633,6 +633,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
	kfree_skb(clone);
	return skb;
}
EXPORT_SYMBOL_GPL(nf_ct_frag6_gather);

void nf_ct_frag6_consume_orig(struct sk_buff *skb)
{
+32 −2
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@
#include <net/netfilter/nf_conntrack_ecache.h>
#include <net/netfilter/nf_conntrack_labels.h>

static spinlock_t nf_connlabels_lock;

static unsigned int label_bits(const struct nf_conn_labels *l)
{
	unsigned int longs = l->words;
@@ -48,7 +50,6 @@ int nf_connlabel_set(struct nf_conn *ct, u16 bit)
}
EXPORT_SYMBOL_GPL(nf_connlabel_set);

#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
static void replace_u32(u32 *address, u32 mask, u32 new)
{
	u32 old, tmp;
@@ -89,7 +90,35 @@ int nf_connlabels_replace(struct nf_conn *ct,
	return 0;
}
EXPORT_SYMBOL_GPL(nf_connlabels_replace);
#endif

int nf_connlabels_get(struct net *net, unsigned int n_bits)
{
	size_t words;

	if (n_bits > (NF_CT_LABELS_MAX_SIZE * BITS_PER_BYTE))
		return -ERANGE;

	words = BITS_TO_LONGS(n_bits);

	spin_lock(&nf_connlabels_lock);
	net->ct.labels_used++;
	if (words > net->ct.label_words)
		net->ct.label_words = words;
	spin_unlock(&nf_connlabels_lock);

	return 0;
}
EXPORT_SYMBOL_GPL(nf_connlabels_get);

void nf_connlabels_put(struct net *net)
{
	spin_lock(&nf_connlabels_lock);
	net->ct.labels_used--;
	if (net->ct.labels_used == 0)
		net->ct.label_words = 0;
	spin_unlock(&nf_connlabels_lock);
}
EXPORT_SYMBOL_GPL(nf_connlabels_put);

static struct nf_ct_ext_type labels_extend __read_mostly = {
	.len    = sizeof(struct nf_conn_labels),
@@ -99,6 +128,7 @@ static struct nf_ct_ext_type labels_extend __read_mostly = {

int nf_conntrack_labels_init(void)
{
	spin_lock_init(&nf_connlabels_lock);
	return nf_ct_extend_register(&labels_extend);
}

Loading