Commit 75a56758 authored by Paul Blakey's avatar Paul Blakey Committed by David S. Miller
Browse files

net/flow_dissector: add connection tracking dissection



Retreives connection tracking zone, mark, label, and state from
a SKB.

Signed-off-by: default avatarPaul Blakey <paulb@mellanox.com>
Signed-off-by: default avatarMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Acked-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b57dc7c1
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -1325,6 +1325,16 @@ void skb_flow_dissect_meta(const struct sk_buff *skb,
			   struct flow_dissector *flow_dissector,
			   void *target_container);

/* Gets a skb connection tracking info, ctinfo map should be a
 * a map of mapsize to translate enum ip_conntrack_info states
 * to user states.
 */
void
skb_flow_dissect_ct(const struct sk_buff *skb,
		    struct flow_dissector *flow_dissector,
		    void *target_container,
		    u16 *ctinfo_map,
		    size_t mapsize);
void
skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
			     struct flow_dissector *flow_dissector,
+15 −0
Original line number Diff line number Diff line
@@ -208,6 +208,20 @@ struct flow_dissector_key_meta {
	int ingress_ifindex;
};

/**
 * struct flow_dissector_key_ct:
 * @ct_state: conntrack state after converting with map
 * @ct_mark: conttrack mark
 * @ct_zone: conntrack zone
 * @ct_labels: conntrack labels
 */
struct flow_dissector_key_ct {
	u16	ct_state;
	u16	ct_zone;
	u32	ct_mark;
	u32	ct_labels[4];
};

enum flow_dissector_key_id {
	FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
	FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
@@ -234,6 +248,7 @@ enum flow_dissector_key_id {
	FLOW_DISSECTOR_KEY_ENC_IP, /* struct flow_dissector_key_ip */
	FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct flow_dissector_key_enc_opts */
	FLOW_DISSECTOR_KEY_META, /* struct flow_dissector_key_meta */
	FLOW_DISSECTOR_KEY_CT, /* struct flow_dissector_key_ct */

	FLOW_DISSECTOR_KEY_MAX,
};
+44 −0
Original line number Diff line number Diff line
@@ -27,6 +27,10 @@
#include <scsi/fc/fc_fcoe.h>
#include <uapi/linux/batadv_packet.h>
#include <linux/bpf.h>
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_labels.h>
#endif

static DEFINE_MUTEX(flow_dissector_mutex);

@@ -231,6 +235,46 @@ skb_flow_dissect_set_enc_addr_type(enum flow_dissector_key_id type,
	ctrl->addr_type = type;
}

void
skb_flow_dissect_ct(const struct sk_buff *skb,
		    struct flow_dissector *flow_dissector,
		    void *target_container,
		    u16 *ctinfo_map,
		    size_t mapsize)
{
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
	struct flow_dissector_key_ct *key;
	enum ip_conntrack_info ctinfo;
	struct nf_conn_labels *cl;
	struct nf_conn *ct;

	if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_CT))
		return;

	ct = nf_ct_get(skb, &ctinfo);
	if (!ct)
		return;

	key = skb_flow_dissector_target(flow_dissector,
					FLOW_DISSECTOR_KEY_CT,
					target_container);

	if (ctinfo < mapsize)
		key->ct_state = ctinfo_map[ctinfo];
#if IS_ENABLED(CONFIG_NF_CONNTRACK_ZONES)
	key->ct_zone = ct->zone.id;
#endif
#if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
	key->ct_mark = ct->mark;
#endif

	cl = nf_ct_labels_find(ct);
	if (cl)
		memcpy(key->ct_labels, cl->bits, sizeof(key->ct_labels));
#endif /* CONFIG_NF_CONNTRACK */
}
EXPORT_SYMBOL(skb_flow_dissect_ct);

void
skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
			     struct flow_dissector *flow_dissector,