Commit 0115552e authored by John Hurley's avatar John Hurley Committed by David S. Miller

nfp: remove false positive offloads in flower vxlan

Pass information to the match offload on whether or not the repr is the
ingress or egress dev. Only accept tunnel matches if repr is the egress
dev.

This means rules such as the following are successfully offloaded:
tc .. add dev vxlan0 .. enc_dst_port 4789 .. action redirect dev nfp_p0

While rules such as the following are rejected:
tc .. add dev nfp_p0 .. enc_dst_port 4789 .. action redirect dev vxlan0

Also reject non tunnel flows that are offloaded to an egress dev.
Non tunnel matches assume that the offload dev is the ingress port and
offload a match accordingly.

Fixes: 611aec10 ("nfp: compile flower vxlan tunnel metadata match fields")
Signed-off-by: default avatarJohn Hurley <john.hurley@netronome.com>
Reviewed-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1a24d4f9
...@@ -131,7 +131,8 @@ static bool nfp_flower_check_higher_than_mac(struct tc_cls_flower_offload *f) ...@@ -131,7 +131,8 @@ static bool nfp_flower_check_higher_than_mac(struct tc_cls_flower_offload *f)
static int static int
nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls, nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls,
struct tc_cls_flower_offload *flow) struct tc_cls_flower_offload *flow,
bool egress)
{ {
struct flow_dissector_key_basic *mask_basic = NULL; struct flow_dissector_key_basic *mask_basic = NULL;
struct flow_dissector_key_basic *key_basic = NULL; struct flow_dissector_key_basic *key_basic = NULL;
...@@ -167,6 +168,9 @@ nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls, ...@@ -167,6 +168,9 @@ nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls,
skb_flow_dissector_target(flow->dissector, skb_flow_dissector_target(flow->dissector,
FLOW_DISSECTOR_KEY_ENC_CONTROL, FLOW_DISSECTOR_KEY_ENC_CONTROL,
flow->key); flow->key);
if (!egress)
return -EOPNOTSUPP;
if (mask_enc_ctl->addr_type != 0xffff || if (mask_enc_ctl->addr_type != 0xffff ||
enc_ctl->addr_type != FLOW_DISSECTOR_KEY_IPV4_ADDRS) enc_ctl->addr_type != FLOW_DISSECTOR_KEY_IPV4_ADDRS)
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -194,6 +198,9 @@ nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls, ...@@ -194,6 +198,9 @@ nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls,
key_layer |= NFP_FLOWER_LAYER_VXLAN; key_layer |= NFP_FLOWER_LAYER_VXLAN;
key_size += sizeof(struct nfp_flower_vxlan); key_size += sizeof(struct nfp_flower_vxlan);
} else if (egress) {
/* Reject non tunnel matches offloaded to egress repr. */
return -EOPNOTSUPP;
} }
if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) { if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
...@@ -315,7 +322,7 @@ nfp_flower_allocate_new(struct nfp_fl_key_ls *key_layer) ...@@ -315,7 +322,7 @@ nfp_flower_allocate_new(struct nfp_fl_key_ls *key_layer)
*/ */
static int static int
nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev, nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev,
struct tc_cls_flower_offload *flow) struct tc_cls_flower_offload *flow, bool egress)
{ {
struct nfp_flower_priv *priv = app->priv; struct nfp_flower_priv *priv = app->priv;
struct nfp_fl_payload *flow_pay; struct nfp_fl_payload *flow_pay;
...@@ -326,7 +333,7 @@ nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev, ...@@ -326,7 +333,7 @@ nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev,
if (!key_layer) if (!key_layer)
return -ENOMEM; return -ENOMEM;
err = nfp_flower_calculate_key_layers(key_layer, flow); err = nfp_flower_calculate_key_layers(key_layer, flow, egress);
if (err) if (err)
goto err_free_key_ls; goto err_free_key_ls;
...@@ -447,7 +454,7 @@ nfp_flower_get_stats(struct nfp_app *app, struct tc_cls_flower_offload *flow) ...@@ -447,7 +454,7 @@ nfp_flower_get_stats(struct nfp_app *app, struct tc_cls_flower_offload *flow)
static int static int
nfp_flower_repr_offload(struct nfp_app *app, struct net_device *netdev, nfp_flower_repr_offload(struct nfp_app *app, struct net_device *netdev,
struct tc_cls_flower_offload *flower) struct tc_cls_flower_offload *flower, bool egress)
{ {
if (!eth_proto_is_802_3(flower->common.protocol) || if (!eth_proto_is_802_3(flower->common.protocol) ||
flower->common.chain_index) flower->common.chain_index)
...@@ -455,7 +462,7 @@ nfp_flower_repr_offload(struct nfp_app *app, struct net_device *netdev, ...@@ -455,7 +462,7 @@ nfp_flower_repr_offload(struct nfp_app *app, struct net_device *netdev,
switch (flower->command) { switch (flower->command) {
case TC_CLSFLOWER_REPLACE: case TC_CLSFLOWER_REPLACE:
return nfp_flower_add_offload(app, netdev, flower); return nfp_flower_add_offload(app, netdev, flower, egress);
case TC_CLSFLOWER_DESTROY: case TC_CLSFLOWER_DESTROY:
return nfp_flower_del_offload(app, netdev, flower); return nfp_flower_del_offload(app, netdev, flower);
case TC_CLSFLOWER_STATS: case TC_CLSFLOWER_STATS:
...@@ -468,7 +475,18 @@ nfp_flower_repr_offload(struct nfp_app *app, struct net_device *netdev, ...@@ -468,7 +475,18 @@ nfp_flower_repr_offload(struct nfp_app *app, struct net_device *netdev,
int nfp_flower_setup_tc_egress_cb(enum tc_setup_type type, void *type_data, int nfp_flower_setup_tc_egress_cb(enum tc_setup_type type, void *type_data,
void *cb_priv) void *cb_priv)
{ {
return -EINVAL; struct nfp_repr *repr = cb_priv;
if (!tc_can_offload(repr->netdev))
return -EOPNOTSUPP;
switch (type) {
case TC_SETUP_CLSFLOWER:
return nfp_flower_repr_offload(repr->app, repr->netdev,
type_data, true);
default:
return -EOPNOTSUPP;
}
} }
static int nfp_flower_setup_tc_block_cb(enum tc_setup_type type, static int nfp_flower_setup_tc_block_cb(enum tc_setup_type type,
...@@ -482,7 +500,7 @@ static int nfp_flower_setup_tc_block_cb(enum tc_setup_type type, ...@@ -482,7 +500,7 @@ static int nfp_flower_setup_tc_block_cb(enum tc_setup_type type,
switch (type) { switch (type) {
case TC_SETUP_CLSFLOWER: case TC_SETUP_CLSFLOWER:
return nfp_flower_repr_offload(repr->app, repr->netdev, return nfp_flower_repr_offload(repr->app, repr->netdev,
type_data); type_data, false);
default: default:
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
......
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