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

Commit 1c976a8c authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'nfp-flower-add-ip-fragmentation-offloading-support'



Pieter Jansen van Vuuren says:

====================
nfp: flower: add ip fragmentation offloading support

This set allows offloading IP fragmentation classification. It Implements
ip fragmentation match offloading for both IPv4 and IPv6 and offloads
frag, nofrag, first and nofirstfrag classification.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 90c00f81 71ea5343
Loading
Loading
Loading
Loading
+13 −9
Original line number Diff line number Diff line
@@ -61,6 +61,9 @@
#define NFP_FLOWER_MASK_MPLS_BOS	BIT(8)
#define NFP_FLOWER_MASK_MPLS_Q		BIT(0)

#define NFP_FL_IP_FRAG_FIRST		BIT(7)
#define NFP_FL_IP_FRAGMENTED		BIT(6)

/* Compressed HW representation of TCP Flags */
#define NFP_FL_TCP_FLAG_URG		BIT(4)
#define NFP_FL_TCP_FLAG_PSH		BIT(3)
@@ -260,6 +263,13 @@ struct nfp_flower_tp_ports {
	__be16 port_dst;
};

struct nfp_flower_ip_ext {
	u8 tos;
	u8 proto;
	u8 ttl;
	u8 flags;
};

/* L3 IPv4 details (3W/12B)
 *    3                   2                   1
 *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
@@ -272,10 +282,7 @@ struct nfp_flower_tp_ports {
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 */
struct nfp_flower_ipv4 {
	u8 tos;
	u8 proto;
	u8 ttl;
	u8 flags;
	struct nfp_flower_ip_ext ip_ext;
	__be32 ipv4_src;
	__be32 ipv4_dst;
};
@@ -284,7 +291,7 @@ struct nfp_flower_ipv4 {
 *    3                   2                   1
 *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |    DSCP   |ECN|   protocol    |          reserved             |
 * |    DSCP   |ECN|   protocol    |      ttl      |     flags     |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |   ipv6_exthdr   | res |            ipv6_flow_label            |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -306,10 +313,7 @@ struct nfp_flower_ipv4 {
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 */
struct nfp_flower_ipv6 {
	u8 tos;
	u8 proto;
	u8 ttl;
	u8 reserved;
	struct nfp_flower_ip_ext ip_ext;
	__be32 ipv6_flow_label_exthdr;
	struct in6_addr ipv6_src;
	struct in6_addr ipv6_dst;
+40 −33
Original line number Diff line number Diff line
@@ -146,26 +146,15 @@ nfp_flower_compile_tport(struct nfp_flower_tp_ports *frame,
}

static void
nfp_flower_compile_ipv4(struct nfp_flower_ipv4 *frame,
nfp_flower_compile_ip_ext(struct nfp_flower_ip_ext *frame,
			  struct tc_cls_flower_offload *flow,
			  bool mask_version)
{
	struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
	struct flow_dissector_key_ipv4_addrs *addr;
	struct flow_dissector_key_basic *basic;

	memset(frame, 0, sizeof(struct nfp_flower_ipv4));

	if (dissector_uses_key(flow->dissector,
			       FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
		addr = skb_flow_dissector_target(flow->dissector,
						 FLOW_DISSECTOR_KEY_IPV4_ADDRS,
						 target);
		frame->ipv4_src = addr->src;
		frame->ipv4_dst = addr->dst;
	}

	if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
		struct flow_dissector_key_basic *basic;

		basic = skb_flow_dissector_target(flow->dissector,
						  FLOW_DISSECTOR_KEY_BASIC,
						  target);
@@ -201,6 +190,40 @@ nfp_flower_compile_ipv4(struct nfp_flower_ipv4 *frame,
		if (tcp_flags & TCPHDR_URG)
			frame->flags |= NFP_FL_TCP_FLAG_URG;
	}

	if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_CONTROL)) {
		struct flow_dissector_key_control *key;

		key = skb_flow_dissector_target(flow->dissector,
						FLOW_DISSECTOR_KEY_CONTROL,
						target);
		if (key->flags & FLOW_DIS_IS_FRAGMENT)
			frame->flags |= NFP_FL_IP_FRAGMENTED;
		if (key->flags & FLOW_DIS_FIRST_FRAG)
			frame->flags |= NFP_FL_IP_FRAG_FIRST;
	}
}

static void
nfp_flower_compile_ipv4(struct nfp_flower_ipv4 *frame,
			struct tc_cls_flower_offload *flow,
			bool mask_version)
{
	struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
	struct flow_dissector_key_ipv4_addrs *addr;

	memset(frame, 0, sizeof(struct nfp_flower_ipv4));

	if (dissector_uses_key(flow->dissector,
			       FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
		addr = skb_flow_dissector_target(flow->dissector,
						 FLOW_DISSECTOR_KEY_IPV4_ADDRS,
						 target);
		frame->ipv4_src = addr->src;
		frame->ipv4_dst = addr->dst;
	}

	nfp_flower_compile_ip_ext(&frame->ip_ext, flow, mask_version);
}

static void
@@ -210,7 +233,6 @@ nfp_flower_compile_ipv6(struct nfp_flower_ipv6 *frame,
{
	struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
	struct flow_dissector_key_ipv6_addrs *addr;
	struct flow_dissector_key_basic *basic;

	memset(frame, 0, sizeof(struct nfp_flower_ipv6));

@@ -223,22 +245,7 @@ nfp_flower_compile_ipv6(struct nfp_flower_ipv6 *frame,
		frame->ipv6_dst = addr->dst;
	}

	if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
		basic = skb_flow_dissector_target(flow->dissector,
						  FLOW_DISSECTOR_KEY_BASIC,
						  target);
		frame->proto = basic->ip_proto;
	}

	if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_IP)) {
		struct flow_dissector_key_ip *flow_ip;

		flow_ip = skb_flow_dissector_target(flow->dissector,
						    FLOW_DISSECTOR_KEY_IP,
						    target);
		frame->tos = flow_ip->tos;
		frame->ttl = flow_ip->ttl;
	}
	nfp_flower_compile_ip_ext(&frame->ip_ext, flow, mask_version);
}

static void
+15 −0
Original line number Diff line number Diff line
@@ -48,6 +48,10 @@
	(TCPHDR_FIN | TCPHDR_SYN | TCPHDR_RST | \
	 TCPHDR_PSH | TCPHDR_URG)

#define NFP_FLOWER_SUPPORTED_CTLFLAGS \
	(FLOW_DIS_IS_FRAGMENT | \
	 FLOW_DIS_FIRST_FRAG)

#define NFP_FLOWER_WHITELIST_DISSECTOR \
	(BIT(FLOW_DISSECTOR_KEY_CONTROL) | \
	 BIT(FLOW_DISSECTOR_KEY_BASIC) | \
@@ -322,6 +326,17 @@ nfp_flower_calculate_key_layers(struct nfp_app *app,
		}
	}

	if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_CONTROL)) {
		struct flow_dissector_key_control *key_ctl;

		key_ctl = skb_flow_dissector_target(flow->dissector,
						    FLOW_DISSECTOR_KEY_CONTROL,
						    flow->key);

		if (key_ctl->flags & ~NFP_FLOWER_SUPPORTED_CTLFLAGS)
			return -EOPNOTSUPP;
	}

	ret_key_ls->key_layer = key_layer;
	ret_key_ls->key_layer_two = key_layer_two;
	ret_key_ls->key_size = key_size;