diff options
author | David S. Miller <davem@davemloft.net> | 2018-03-26 13:01:10 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-03-26 13:01:10 -0400 |
commit | 1c976a8c52f0a6c5ed674803908bb5a8993d4980 (patch) | |
tree | 2cb0f421ad2fbba42030a44d4b2c67cf63d47b0c | |
parent | 90c00f81548e86ff92fb9f6031c2c3d70f04d50b (diff) | |
parent | 71ea5343a01cad36d7c44bea07a79dd96049e6c0 (diff) |
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: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/flower/cmsg.h | 22 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/flower/match.c | 73 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/flower/offload.c | 15 |
3 files changed, 68 insertions, 42 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h index 28c1cd5b823b..3f46d836d1b8 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h +++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h @@ -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; diff --git a/drivers/net/ethernet/netronome/nfp/flower/match.c b/drivers/net/ethernet/netronome/nfp/flower/match.c index b3bc8279d4fb..91935405f586 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/match.c +++ b/drivers/net/ethernet/netronome/nfp/flower/match.c @@ -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 diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c index f3586c519805..114d2ab02a38 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/offload.c +++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c @@ -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; |