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

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
......@@ -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;
......
......@@ -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,
struct tc_cls_flower_offload *flow,
bool mask_version)
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
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment