Skip to content

Commit

Permalink
net/flow_dissector: add connection tracking dissection
Browse files Browse the repository at this point in the history
Retreives connection tracking zone, mark, label, and state from
a SKB.

Signed-off-by: Paul Blakey <paulb@mellanox.com>
Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Paul Blakey authored and David S. Miller committed Jul 9, 2019
1 parent b57dc7c commit 75a5675
Showing 3 changed files with 69 additions and 0 deletions.
10 changes: 10 additions & 0 deletions include/linux/skbuff.h
Original file line number Diff line number Diff line change
@@ -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 changes: 15 additions & 0 deletions include/net/flow_dissector.h
Original file line number Diff line number Diff line change
@@ -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 changes: 44 additions & 0 deletions net/core/flow_dissector.c
Original file line number Diff line number Diff line change
@@ -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,

0 comments on commit 75a5675

Please sign in to comment.