Skip to content

Commit

Permalink
nfp: flower: compile Geneve match fields
Browse files Browse the repository at this point in the history
Compile Geneve match fields for offloading to the NFP. The addition of
Geneve overflows the 8 bit key_layer field, so apply extended metadata to
the match cmsg allowing up to 32 more key_layer fields.

Rather than adding new Geneve blocks, move the vxlan code to generic ipv4
udp tunnel structs and use these for both vxlan and Geneve.

Matches are only supported when specifically mentioning well known port
6081. Geneve tunnel options are not yet included in the match.

Only offload Geneve if the fw supports it - include check for this.

Signed-off-by: John Hurley <john.hurley@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Simon Horman <simon.horman@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
John Hurley authored and David S. Miller committed Dec 19, 2017
1 parent 7399734 commit bedeca1
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 42 deletions.
32 changes: 21 additions & 11 deletions drivers/net/ethernet/netronome/nfp/flower/cmsg.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
#include "../nfp_app.h"
#include "../nfpcore/nfp_cpp.h"

#define NFP_FLOWER_LAYER_META BIT(0)
#define NFP_FLOWER_LAYER_EXT_META BIT(0)
#define NFP_FLOWER_LAYER_PORT BIT(1)
#define NFP_FLOWER_LAYER_MAC BIT(2)
#define NFP_FLOWER_LAYER_TP BIT(3)
Expand All @@ -50,6 +50,8 @@
#define NFP_FLOWER_LAYER_CT BIT(6)
#define NFP_FLOWER_LAYER_VXLAN BIT(7)

#define NFP_FLOWER_LAYER2_GENEVE BIT(5)

#define NFP_FLOWER_MASK_VLAN_PRIO GENMASK(15, 13)
#define NFP_FLOWER_MASK_VLAN_CFI BIT(12)
#define NFP_FLOWER_MASK_VLAN_VID GENMASK(11, 0)
Expand Down Expand Up @@ -105,6 +107,7 @@
enum nfp_flower_tun_type {
NFP_FL_TUNNEL_NONE = 0,
NFP_FL_TUNNEL_VXLAN = 2,
NFP_FL_TUNNEL_GENEVE = 4,
};

struct nfp_fl_act_head {
Expand Down Expand Up @@ -198,6 +201,18 @@ struct nfp_flower_meta_tci {
__be16 tci;
};

/* Extended metadata for additional key_layers (1W/4B)
* ----------------------------------------------------------------
* 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
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | nfp_flow_key_layer2 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
struct nfp_flower_ext_meta {
__be32 nfp_flow_key_layer2;
};

/* Port details (1W/4B)
* ----------------------------------------------------------------
* 3 2 1
Expand Down Expand Up @@ -296,7 +311,7 @@ struct nfp_flower_ipv6 {
struct in6_addr ipv6_dst;
};

/* Flow Frame VXLAN --> Tunnel details (4W/16B)
/* Flow Frame IPv4 UDP TUNNEL --> Tunnel details (4W/16B)
* -----------------------------------------------------------------
* 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
Expand All @@ -305,22 +320,17 @@ struct nfp_flower_ipv6 {
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ipv4_addr_dst |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | tun_flags | tos | ttl |
* | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | gpe_flags | Reserved | Next Protocol |
* | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | VNI | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
struct nfp_flower_vxlan {
struct nfp_flower_ipv4_udp_tun {
__be32 ip_src;
__be32 ip_dst;
__be16 tun_flags;
u8 tos;
u8 ttl;
u8 gpe_flags;
u8 reserved[2];
u8 nxt_proto;
__be32 reserved[2];
__be32 tun_id;
};

Expand Down
9 changes: 8 additions & 1 deletion drivers/net/ethernet/netronome/nfp/flower/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
#ifndef __NFP_FLOWER_H__
#define __NFP_FLOWER_H__ 1

#include "cmsg.h"

#include <linux/circ_buf.h>
#include <linux/hashtable.h>
#include <linux/time64.h>
Expand All @@ -58,6 +60,10 @@ struct nfp_app;
#define NFP_FL_MASK_ID_LOCATION 1

#define NFP_FL_VXLAN_PORT 4789
#define NFP_FL_GENEVE_PORT 6081

/* Extra features bitmap. */
#define NFP_FL_FEATS_GENEVE BIT(0)

struct nfp_fl_mask_id {
struct circ_buf mask_id_free_list;
Expand Down Expand Up @@ -174,7 +180,8 @@ int nfp_flower_setup_tc(struct nfp_app *app, struct net_device *netdev,
int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow,
struct nfp_fl_key_ls *key_ls,
struct net_device *netdev,
struct nfp_fl_payload *nfp_flow);
struct nfp_fl_payload *nfp_flow,
enum nfp_flower_tun_type tun_type);
int nfp_flower_compile_action(struct tc_cls_flower_offload *flow,
struct net_device *netdev,
struct nfp_fl_payload *nfp_flow);
Expand Down
55 changes: 33 additions & 22 deletions drivers/net/ethernet/netronome/nfp/flower/match.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ nfp_flower_compile_meta_tci(struct nfp_flower_meta_tci *frame,
}
}

static void
nfp_flower_compile_ext_meta(struct nfp_flower_ext_meta *frame, u32 key_ext)
{
frame->nfp_flow_key_layer2 = cpu_to_be32(key_ext);
}

static int
nfp_flower_compile_port(struct nfp_flower_in_port *frame, u32 cmsg_port,
bool mask_version, enum nfp_flower_tun_type tun_type)
Expand Down Expand Up @@ -216,16 +222,15 @@ nfp_flower_compile_ipv6(struct nfp_flower_ipv6 *frame,
}

static void
nfp_flower_compile_vxlan(struct nfp_flower_vxlan *frame,
struct tc_cls_flower_offload *flow,
bool mask_version)
nfp_flower_compile_ipv4_udp_tun(struct nfp_flower_ipv4_udp_tun *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 *vxlan_ips;
struct flow_dissector_key_ipv4_addrs *tun_ips;
struct flow_dissector_key_keyid *vni;

/* Wildcard TOS/TTL/GPE_FLAGS/NXT_PROTO for now. */
memset(frame, 0, sizeof(struct nfp_flower_vxlan));
memset(frame, 0, sizeof(struct nfp_flower_ipv4_udp_tun));

if (dissector_uses_key(flow->dissector,
FLOW_DISSECTOR_KEY_ENC_KEYID)) {
Expand All @@ -240,29 +245,26 @@ nfp_flower_compile_vxlan(struct nfp_flower_vxlan *frame,

if (dissector_uses_key(flow->dissector,
FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS)) {
vxlan_ips =
tun_ips =
skb_flow_dissector_target(flow->dissector,
FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS,
target);
frame->ip_src = vxlan_ips->src;
frame->ip_dst = vxlan_ips->dst;
frame->ip_src = tun_ips->src;
frame->ip_dst = tun_ips->dst;
}
}

int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow,
struct nfp_fl_key_ls *key_ls,
struct net_device *netdev,
struct nfp_fl_payload *nfp_flow)
struct nfp_fl_payload *nfp_flow,
enum nfp_flower_tun_type tun_type)
{
enum nfp_flower_tun_type tun_type = NFP_FL_TUNNEL_NONE;
struct nfp_repr *netdev_repr;
int err;
u8 *ext;
u8 *msk;

if (key_ls->key_layer & NFP_FLOWER_LAYER_VXLAN)
tun_type = NFP_FL_TUNNEL_VXLAN;

memset(nfp_flow->unmasked_data, 0, key_ls->key_size);
memset(nfp_flow->mask_data, 0, key_ls->key_size);

Expand All @@ -278,6 +280,16 @@ int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow,
ext += sizeof(struct nfp_flower_meta_tci);
msk += sizeof(struct nfp_flower_meta_tci);

/* Populate Extended Metadata if Required. */
if (NFP_FLOWER_LAYER_EXT_META & key_ls->key_layer) {
nfp_flower_compile_ext_meta((struct nfp_flower_ext_meta *)ext,
key_ls->key_layer_two);
nfp_flower_compile_ext_meta((struct nfp_flower_ext_meta *)msk,
key_ls->key_layer_two);
ext += sizeof(struct nfp_flower_ext_meta);
msk += sizeof(struct nfp_flower_ext_meta);
}

/* Populate Exact Port data. */
err = nfp_flower_compile_port((struct nfp_flower_in_port *)ext,
nfp_repr_get_port_id(netdev),
Expand Down Expand Up @@ -339,18 +351,17 @@ int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow,
msk += sizeof(struct nfp_flower_ipv6);
}

if (key_ls->key_layer & NFP_FLOWER_LAYER_VXLAN) {
if (key_ls->key_layer & NFP_FLOWER_LAYER_VXLAN ||
key_ls->key_layer_two & NFP_FLOWER_LAYER2_GENEVE) {
__be32 tun_dst;

/* Populate Exact VXLAN Data. */
nfp_flower_compile_vxlan((struct nfp_flower_vxlan *)ext,
flow, false);
nfp_flower_compile_ipv4_udp_tun((void *)ext, flow, false);
/* Populate Mask VXLAN Data. */
nfp_flower_compile_vxlan((struct nfp_flower_vxlan *)msk,
flow, true);
tun_dst = ((struct nfp_flower_vxlan *)ext)->ip_dst;
ext += sizeof(struct nfp_flower_vxlan);
msk += sizeof(struct nfp_flower_vxlan);
nfp_flower_compile_ipv4_udp_tun((void *)msk, flow, true);
tun_dst = ((struct nfp_flower_ipv4_udp_tun *)ext)->ip_dst;
ext += sizeof(struct nfp_flower_ipv4_udp_tun);
msk += sizeof(struct nfp_flower_ipv4_udp_tun);

/* Configure tunnel end point MAC. */
if (nfp_netdev_is_nfp_repr(netdev)) {
Expand Down
37 changes: 29 additions & 8 deletions drivers/net/ethernet/netronome/nfp/flower/offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,15 @@ static bool nfp_flower_check_higher_than_mac(struct tc_cls_flower_offload *f)
}

static int
nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls,
nfp_flower_calculate_key_layers(struct nfp_app *app,
struct nfp_fl_key_ls *ret_key_ls,
struct tc_cls_flower_offload *flow,
bool egress)
bool egress,
enum nfp_flower_tun_type *tun_type)
{
struct flow_dissector_key_basic *mask_basic = NULL;
struct flow_dissector_key_basic *key_basic = NULL;
struct nfp_flower_priv *priv = app->priv;
u32 key_layer_two;
u8 key_layer;
int key_size;
Expand Down Expand Up @@ -197,12 +200,27 @@ nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls,
FLOW_DISSECTOR_KEY_ENC_PORTS,
flow->key);

if (mask_enc_ports->dst != cpu_to_be16(~0) ||
enc_ports->dst != htons(NFP_FL_VXLAN_PORT))
if (mask_enc_ports->dst != cpu_to_be16(~0))
return -EOPNOTSUPP;

key_layer |= NFP_FLOWER_LAYER_VXLAN;
key_size += sizeof(struct nfp_flower_vxlan);
switch (enc_ports->dst) {
case htons(NFP_FL_VXLAN_PORT):
*tun_type = NFP_FL_TUNNEL_VXLAN;
key_layer |= NFP_FLOWER_LAYER_VXLAN;
key_size += sizeof(struct nfp_flower_ipv4_udp_tun);
break;
case htons(NFP_FL_GENEVE_PORT):
if (!(priv->flower_ext_feats & NFP_FL_FEATS_GENEVE))
return -EOPNOTSUPP;
*tun_type = NFP_FL_TUNNEL_GENEVE;
key_layer |= NFP_FLOWER_LAYER_EXT_META;
key_size += sizeof(struct nfp_flower_ext_meta);
key_layer_two |= NFP_FLOWER_LAYER2_GENEVE;
key_size += sizeof(struct nfp_flower_ipv4_udp_tun);
break;
default:
return -EOPNOTSUPP;
}
} else if (egress) {
/* Reject non tunnel matches offloaded to egress repr. */
return -EOPNOTSUPP;
Expand Down Expand Up @@ -330,6 +348,7 @@ static int
nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev,
struct tc_cls_flower_offload *flow, bool egress)
{
enum nfp_flower_tun_type tun_type = NFP_FL_TUNNEL_NONE;
struct nfp_flower_priv *priv = app->priv;
struct nfp_fl_payload *flow_pay;
struct nfp_fl_key_ls *key_layer;
Expand All @@ -339,7 +358,8 @@ nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev,
if (!key_layer)
return -ENOMEM;

err = nfp_flower_calculate_key_layers(key_layer, flow, egress);
err = nfp_flower_calculate_key_layers(app, key_layer, flow, egress,
&tun_type);
if (err)
goto err_free_key_ls;

Expand All @@ -349,7 +369,8 @@ nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev,
goto err_free_key_ls;
}

err = nfp_flower_compile_flow_match(flow, key_layer, netdev, flow_pay);
err = nfp_flower_compile_flow_match(flow, key_layer, netdev, flow_pay,
tun_type);
if (err)
goto err_destroy_flow;

Expand Down

0 comments on commit bedeca1

Please sign in to comment.