Skip to content

Commit

Permalink
nfp: flower: offload pre-tunnel rules
Browse files Browse the repository at this point in the history
Pre-tunnel rules are TC flower and OvS rules that forward a packet to the
tunnel end point where it can then pass through the network stack and be
decapsulated. These are required if the tunnel end point is, say, an OvS
internal port.

Currently, firmware determines that a packet is in a tunnel and decaps it
if it has a known destination IP and MAC address. However, this bypasses
the flower pre-tunnel rule and so does not update the stats. Further to
this it ignores VLANs that may exist outside of the tunnel header.

Offload pre-tunnel rules to the NFP. This embeds the pre-tunnel rule into
the tunnel decap process based on (firmware) mac index and VLAN. This
means that decap can be carried out correctly with VLANs and that stats
can be updated for all kernel rules correctly.

Signed-off-by: John Hurley <john.hurley@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
John Hurley authored and David S. Miller committed Aug 6, 2019
1 parent 120ffd8 commit f12725d
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 2 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/netronome/nfp/flower/cmsg.h
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ enum nfp_flower_cmsg_type_port {
NFP_FLOWER_CMSG_TYPE_QOS_MOD = 18,
NFP_FLOWER_CMSG_TYPE_QOS_DEL = 19,
NFP_FLOWER_CMSG_TYPE_QOS_STATS = 20,
NFP_FLOWER_CMSG_TYPE_PRE_TUN_RULE = 21,
NFP_FLOWER_CMSG_TYPE_MAX = 32,
};

Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/netronome/nfp/flower/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,7 @@ static int nfp_flower_init(struct nfp_app *app)

INIT_LIST_HEAD(&app_priv->indr_block_cb_priv);
INIT_LIST_HEAD(&app_priv->non_repr_priv);
app_priv->pre_tun_rule_cnt = 0;

return 0;

Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/netronome/nfp/flower/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ struct nfp_fl_internal_ports {
* @qos_stats_work: Workqueue for qos stats processing
* @qos_rate_limiters: Current active qos rate limiters
* @qos_stats_lock: Lock on qos stats updates
* @pre_tun_rule_cnt: Number of pre-tunnel rules offloaded
*/
struct nfp_flower_priv {
struct nfp_app *app;
Expand Down Expand Up @@ -194,6 +195,7 @@ struct nfp_flower_priv {
struct delayed_work qos_stats_work;
unsigned int qos_rate_limiters;
spinlock_t qos_stats_lock; /* Protect the qos stats */
int pre_tun_rule_cnt;
};

/**
Expand Down Expand Up @@ -284,6 +286,7 @@ struct nfp_fl_payload {
struct {
struct net_device *dev;
__be16 vlan_tci;
__be16 port_idx;
} pre_tun_rule;
};

Expand Down
79 changes: 77 additions & 2 deletions drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,23 @@

#define NFP_FL_MAX_ROUTES 32

#define NFP_TUN_PRE_TUN_RULE_LIMIT 32
#define NFP_TUN_PRE_TUN_RULE_DEL 0x1

/**
* struct nfp_tun_pre_run_rule - rule matched before decap
* @flags: options for the rule offset
* @port_idx: index of destination MAC address for the rule
* @vlan_tci: VLAN info associated with MAC
* @host_ctx_id: stats context of rule to update
*/
struct nfp_tun_pre_tun_rule {
__be32 flags;
__be16 port_idx;
__be16 vlan_tci;
__be32 host_ctx_id;
};

/**
* struct nfp_tun_active_tuns - periodic message of active tunnels
* @seq: sequence number of the message
Expand Down Expand Up @@ -835,13 +852,71 @@ int nfp_tunnel_mac_event_handler(struct nfp_app *app,
int nfp_flower_xmit_pre_tun_flow(struct nfp_app *app,
struct nfp_fl_payload *flow)
{
return -EOPNOTSUPP;
struct nfp_flower_priv *app_priv = app->priv;
struct nfp_tun_offloaded_mac *mac_entry;
struct nfp_tun_pre_tun_rule payload;
struct net_device *internal_dev;
int err;

if (app_priv->pre_tun_rule_cnt == NFP_TUN_PRE_TUN_RULE_LIMIT)
return -ENOSPC;

memset(&payload, 0, sizeof(struct nfp_tun_pre_tun_rule));

internal_dev = flow->pre_tun_rule.dev;
payload.vlan_tci = flow->pre_tun_rule.vlan_tci;
payload.host_ctx_id = flow->meta.host_ctx_id;

/* Lookup MAC index for the pre-tunnel rule egress device.
* Note that because the device is always an internal port, it will
* have a constant global index so does not need to be tracked.
*/
mac_entry = nfp_tunnel_lookup_offloaded_macs(app,
internal_dev->dev_addr);
if (!mac_entry)
return -ENOENT;

payload.port_idx = cpu_to_be16(mac_entry->index);

/* Copy mac id and vlan to flow - dev may not exist at delete time. */
flow->pre_tun_rule.vlan_tci = payload.vlan_tci;
flow->pre_tun_rule.port_idx = payload.port_idx;

err = nfp_flower_xmit_tun_conf(app, NFP_FLOWER_CMSG_TYPE_PRE_TUN_RULE,
sizeof(struct nfp_tun_pre_tun_rule),
(unsigned char *)&payload, GFP_KERNEL);
if (err)
return err;

app_priv->pre_tun_rule_cnt++;

return 0;
}

int nfp_flower_xmit_pre_tun_del_flow(struct nfp_app *app,
struct nfp_fl_payload *flow)
{
return -EOPNOTSUPP;
struct nfp_flower_priv *app_priv = app->priv;
struct nfp_tun_pre_tun_rule payload;
u32 tmp_flags = 0;
int err;

memset(&payload, 0, sizeof(struct nfp_tun_pre_tun_rule));

tmp_flags |= NFP_TUN_PRE_TUN_RULE_DEL;
payload.flags = cpu_to_be32(tmp_flags);
payload.vlan_tci = flow->pre_tun_rule.vlan_tci;
payload.port_idx = flow->pre_tun_rule.port_idx;

err = nfp_flower_xmit_tun_conf(app, NFP_FLOWER_CMSG_TYPE_PRE_TUN_RULE,
sizeof(struct nfp_tun_pre_tun_rule),
(unsigned char *)&payload, GFP_KERNEL);
if (err)
return err;

app_priv->pre_tun_rule_cnt--;

return 0;
}

int nfp_tunnel_config_start(struct nfp_app *app)
Expand Down

0 comments on commit f12725d

Please sign in to comment.