Commit 73867881 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso Committed by David S. Miller

drivers: net: use flow action infrastructure

This patch updates drivers to use the new flow action infrastructure.
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
Acked-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3b1903ef
...@@ -61,9 +61,9 @@ static u16 bnxt_flow_get_dst_fid(struct bnxt *pf_bp, struct net_device *dev) ...@@ -61,9 +61,9 @@ static u16 bnxt_flow_get_dst_fid(struct bnxt *pf_bp, struct net_device *dev)
static int bnxt_tc_parse_redir(struct bnxt *bp, static int bnxt_tc_parse_redir(struct bnxt *bp,
struct bnxt_tc_actions *actions, struct bnxt_tc_actions *actions,
const struct tc_action *tc_act) const struct flow_action_entry *act)
{ {
struct net_device *dev = tcf_mirred_dev(tc_act); struct net_device *dev = act->dev;
if (!dev) { if (!dev) {
netdev_info(bp->dev, "no dev in mirred action"); netdev_info(bp->dev, "no dev in mirred action");
...@@ -77,16 +77,16 @@ static int bnxt_tc_parse_redir(struct bnxt *bp, ...@@ -77,16 +77,16 @@ static int bnxt_tc_parse_redir(struct bnxt *bp,
static int bnxt_tc_parse_vlan(struct bnxt *bp, static int bnxt_tc_parse_vlan(struct bnxt *bp,
struct bnxt_tc_actions *actions, struct bnxt_tc_actions *actions,
const struct tc_action *tc_act) const struct flow_action_entry *act)
{ {
switch (tcf_vlan_action(tc_act)) { switch (act->id) {
case TCA_VLAN_ACT_POP: case FLOW_ACTION_VLAN_POP:
actions->flags |= BNXT_TC_ACTION_FLAG_POP_VLAN; actions->flags |= BNXT_TC_ACTION_FLAG_POP_VLAN;
break; break;
case TCA_VLAN_ACT_PUSH: case FLOW_ACTION_VLAN_PUSH:
actions->flags |= BNXT_TC_ACTION_FLAG_PUSH_VLAN; actions->flags |= BNXT_TC_ACTION_FLAG_PUSH_VLAN;
actions->push_vlan_tci = htons(tcf_vlan_push_vid(tc_act)); actions->push_vlan_tci = htons(act->vlan.vid);
actions->push_vlan_tpid = tcf_vlan_push_proto(tc_act); actions->push_vlan_tpid = act->vlan.proto;
break; break;
default: default:
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -96,10 +96,10 @@ static int bnxt_tc_parse_vlan(struct bnxt *bp, ...@@ -96,10 +96,10 @@ static int bnxt_tc_parse_vlan(struct bnxt *bp,
static int bnxt_tc_parse_tunnel_set(struct bnxt *bp, static int bnxt_tc_parse_tunnel_set(struct bnxt *bp,
struct bnxt_tc_actions *actions, struct bnxt_tc_actions *actions,
const struct tc_action *tc_act) const struct flow_action_entry *act)
{ {
struct ip_tunnel_info *tun_info = tcf_tunnel_info(tc_act); const struct ip_tunnel_info *tun_info = act->tunnel;
struct ip_tunnel_key *tun_key = &tun_info->key; const struct ip_tunnel_key *tun_key = &tun_info->key;
if (ip_tunnel_info_af(tun_info) != AF_INET) { if (ip_tunnel_info_af(tun_info) != AF_INET) {
netdev_info(bp->dev, "only IPv4 tunnel-encap is supported"); netdev_info(bp->dev, "only IPv4 tunnel-encap is supported");
...@@ -113,51 +113,43 @@ static int bnxt_tc_parse_tunnel_set(struct bnxt *bp, ...@@ -113,51 +113,43 @@ static int bnxt_tc_parse_tunnel_set(struct bnxt *bp,
static int bnxt_tc_parse_actions(struct bnxt *bp, static int bnxt_tc_parse_actions(struct bnxt *bp,
struct bnxt_tc_actions *actions, struct bnxt_tc_actions *actions,
struct tcf_exts *tc_exts) struct flow_action *flow_action)
{ {
const struct tc_action *tc_act; struct flow_action_entry *act;
int i, rc; int i, rc;
if (!tcf_exts_has_actions(tc_exts)) { if (!flow_action_has_entries(flow_action)) {
netdev_info(bp->dev, "no actions"); netdev_info(bp->dev, "no actions");
return -EINVAL; return -EINVAL;
} }
tcf_exts_for_each_action(i, tc_act, tc_exts) { flow_action_for_each(i, act, flow_action) {
/* Drop action */ switch (act->id) {
if (is_tcf_gact_shot(tc_act)) { case FLOW_ACTION_DROP:
actions->flags |= BNXT_TC_ACTION_FLAG_DROP; actions->flags |= BNXT_TC_ACTION_FLAG_DROP;
return 0; /* don't bother with other actions */ return 0; /* don't bother with other actions */
} case FLOW_ACTION_REDIRECT:
rc = bnxt_tc_parse_redir(bp, actions, act);
/* Redirect action */
if (is_tcf_mirred_egress_redirect(tc_act)) {
rc = bnxt_tc_parse_redir(bp, actions, tc_act);
if (rc) if (rc)
return rc; return rc;
continue; break;
} case FLOW_ACTION_VLAN_POP:
case FLOW_ACTION_VLAN_PUSH:
/* Push/pop VLAN */ case FLOW_ACTION_VLAN_MANGLE:
if (is_tcf_vlan(tc_act)) { rc = bnxt_tc_parse_vlan(bp, actions, act);
rc = bnxt_tc_parse_vlan(bp, actions, tc_act);
if (rc) if (rc)
return rc; return rc;
continue; break;
} case FLOW_ACTION_TUNNEL_ENCAP:
rc = bnxt_tc_parse_tunnel_set(bp, actions, act);
/* Tunnel encap */
if (is_tcf_tunnel_set(tc_act)) {
rc = bnxt_tc_parse_tunnel_set(bp, actions, tc_act);
if (rc) if (rc)
return rc; return rc;
continue; break;
} case FLOW_ACTION_TUNNEL_DECAP:
/* Tunnel decap */
if (is_tcf_tunnel_release(tc_act)) {
actions->flags |= BNXT_TC_ACTION_FLAG_TUNNEL_DECAP; actions->flags |= BNXT_TC_ACTION_FLAG_TUNNEL_DECAP;
continue; break;
default:
break;
} }
} }
...@@ -308,7 +300,7 @@ static int bnxt_tc_parse_flow(struct bnxt *bp, ...@@ -308,7 +300,7 @@ static int bnxt_tc_parse_flow(struct bnxt *bp,
flow->tun_mask.tp_src = match.mask->src; flow->tun_mask.tp_src = match.mask->src;
} }
return bnxt_tc_parse_actions(bp, &flow->actions, tc_flow_cmd->exts); return bnxt_tc_parse_actions(bp, &flow->actions, &rule->action);
} }
static int bnxt_hwrm_cfa_flow_free(struct bnxt *bp, static int bnxt_hwrm_cfa_flow_free(struct bnxt *bp,
......
...@@ -292,7 +292,7 @@ static void process_pedit_field(struct ch_filter_specification *fs, u32 val, ...@@ -292,7 +292,7 @@ static void process_pedit_field(struct ch_filter_specification *fs, u32 val,
u32 mask, u32 offset, u8 htype) u32 mask, u32 offset, u8 htype)
{ {
switch (htype) { switch (htype) {
case TCA_PEDIT_KEY_EX_HDR_TYPE_ETH: case FLOW_ACT_MANGLE_HDR_TYPE_ETH:
switch (offset) { switch (offset) {
case PEDIT_ETH_DMAC_31_0: case PEDIT_ETH_DMAC_31_0:
fs->newdmac = 1; fs->newdmac = 1;
...@@ -310,7 +310,7 @@ static void process_pedit_field(struct ch_filter_specification *fs, u32 val, ...@@ -310,7 +310,7 @@ static void process_pedit_field(struct ch_filter_specification *fs, u32 val,
offload_pedit(fs, val, mask, ETH_SMAC_47_16); offload_pedit(fs, val, mask, ETH_SMAC_47_16);
} }
break; break;
case TCA_PEDIT_KEY_EX_HDR_TYPE_IP4: case FLOW_ACT_MANGLE_HDR_TYPE_IP4:
switch (offset) { switch (offset) {
case PEDIT_IP4_SRC: case PEDIT_IP4_SRC:
offload_pedit(fs, val, mask, IP4_SRC); offload_pedit(fs, val, mask, IP4_SRC);
...@@ -320,7 +320,7 @@ static void process_pedit_field(struct ch_filter_specification *fs, u32 val, ...@@ -320,7 +320,7 @@ static void process_pedit_field(struct ch_filter_specification *fs, u32 val,
} }
fs->nat_mode = NAT_MODE_ALL; fs->nat_mode = NAT_MODE_ALL;
break; break;
case TCA_PEDIT_KEY_EX_HDR_TYPE_IP6: case FLOW_ACT_MANGLE_HDR_TYPE_IP6:
switch (offset) { switch (offset) {
case PEDIT_IP6_SRC_31_0: case PEDIT_IP6_SRC_31_0:
offload_pedit(fs, val, mask, IP6_SRC_31_0); offload_pedit(fs, val, mask, IP6_SRC_31_0);
...@@ -348,7 +348,7 @@ static void process_pedit_field(struct ch_filter_specification *fs, u32 val, ...@@ -348,7 +348,7 @@ static void process_pedit_field(struct ch_filter_specification *fs, u32 val,
} }
fs->nat_mode = NAT_MODE_ALL; fs->nat_mode = NAT_MODE_ALL;
break; break;
case TCA_PEDIT_KEY_EX_HDR_TYPE_TCP: case FLOW_ACT_MANGLE_HDR_TYPE_TCP:
switch (offset) { switch (offset) {
case PEDIT_TCP_SPORT_DPORT: case PEDIT_TCP_SPORT_DPORT:
if (~mask & PEDIT_TCP_UDP_SPORT_MASK) if (~mask & PEDIT_TCP_UDP_SPORT_MASK)
...@@ -361,7 +361,7 @@ static void process_pedit_field(struct ch_filter_specification *fs, u32 val, ...@@ -361,7 +361,7 @@ static void process_pedit_field(struct ch_filter_specification *fs, u32 val,
} }
fs->nat_mode = NAT_MODE_ALL; fs->nat_mode = NAT_MODE_ALL;
break; break;
case TCA_PEDIT_KEY_EX_HDR_TYPE_UDP: case FLOW_ACT_MANGLE_HDR_TYPE_UDP:
switch (offset) { switch (offset) {
case PEDIT_UDP_SPORT_DPORT: case PEDIT_UDP_SPORT_DPORT:
if (~mask & PEDIT_TCP_UDP_SPORT_MASK) if (~mask & PEDIT_TCP_UDP_SPORT_MASK)
...@@ -380,56 +380,63 @@ static void cxgb4_process_flow_actions(struct net_device *in, ...@@ -380,56 +380,63 @@ static void cxgb4_process_flow_actions(struct net_device *in,
struct tc_cls_flower_offload *cls, struct tc_cls_flower_offload *cls,
struct ch_filter_specification *fs) struct ch_filter_specification *fs)
{ {
const struct tc_action *a; struct flow_rule *rule = tc_cls_flower_offload_flow_rule(cls);
struct flow_action_entry *act;
int i; int i;
tcf_exts_for_each_action(i, a, cls->exts) { flow_action_for_each(i, act, &rule->action) {
if (is_tcf_gact_ok(a)) { switch (act->id) {
case FLOW_ACTION_ACCEPT:
fs->action = FILTER_PASS; fs->action = FILTER_PASS;
} else if (is_tcf_gact_shot(a)) { break;
case FLOW_ACTION_DROP:
fs->action = FILTER_DROP; fs->action = FILTER_DROP;
} else if (is_tcf_mirred_egress_redirect(a)) { break;
struct net_device *out = tcf_mirred_dev(a); case FLOW_ACTION_REDIRECT: {
struct net_device *out = act->dev;
struct port_info *pi = netdev_priv(out); struct port_info *pi = netdev_priv(out);
fs->action = FILTER_SWITCH; fs->action = FILTER_SWITCH;
fs->eport = pi->port_id; fs->eport = pi->port_id;
} else if (is_tcf_vlan(a)) { }
u32 vlan_action = tcf_vlan_action(a); break;
u8 prio = tcf_vlan_push_prio(a); case FLOW_ACTION_VLAN_POP:
u16 vid = tcf_vlan_push_vid(a); case FLOW_ACTION_VLAN_PUSH:
case FLOW_ACTION_VLAN_MANGLE: {
u8 prio = act->vlan.prio;
u16 vid = act->vlan.vid;
u16 vlan_tci = (prio << VLAN_PRIO_SHIFT) | vid; u16 vlan_tci = (prio << VLAN_PRIO_SHIFT) | vid;
switch (act->id) {
switch (vlan_action) { case FLOW_ACTION_VLAN_POP:
case TCA_VLAN_ACT_POP:
fs->newvlan |= VLAN_REMOVE; fs->newvlan |= VLAN_REMOVE;
break; break;
case TCA_VLAN_ACT_PUSH: case FLOW_ACTION_VLAN_PUSH:
fs->newvlan |= VLAN_INSERT; fs->newvlan |= VLAN_INSERT;
fs->vlan = vlan_tci; fs->vlan = vlan_tci;
break; break;
case TCA_VLAN_ACT_MODIFY: case FLOW_ACTION_VLAN_MANGLE:
fs->newvlan |= VLAN_REWRITE; fs->newvlan |= VLAN_REWRITE;
fs->vlan = vlan_tci; fs->vlan = vlan_tci;
break; break;
default: default:
break; break;
} }
} else if (is_tcf_pedit(a)) { }
break;
case FLOW_ACTION_MANGLE: {
u32 mask, val, offset; u32 mask, val, offset;
int nkeys, i;
u8 htype; u8 htype;
nkeys = tcf_pedit_nkeys(a); htype = act->mangle.htype;
for (i = 0; i < nkeys; i++) { mask = act->mangle.mask;
htype = tcf_pedit_htype(a, i); val = act->mangle.val;
mask = tcf_pedit_mask(a, i); offset = act->mangle.offset;
val = tcf_pedit_val(a, i);
offset = tcf_pedit_offset(a, i);
process_pedit_field(fs, val, mask, offset, process_pedit_field(fs, val, mask, offset, htype);
htype);
} }
break;
default:
break;
} }
} }
} }
...@@ -448,27 +455,17 @@ static bool valid_l4_mask(u32 mask) ...@@ -448,27 +455,17 @@ static bool valid_l4_mask(u32 mask)
} }
static bool valid_pedit_action(struct net_device *dev, static bool valid_pedit_action(struct net_device *dev,
const struct tc_action *a) const struct flow_action_entry *act)
{ {
u32 mask, offset; u32 mask, offset;
u8 cmd, htype; u8 htype;
int nkeys, i;
htype = act->mangle.htype;
nkeys = tcf_pedit_nkeys(a); mask = act->mangle.mask;
for (i = 0; i < nkeys; i++) { offset = act->mangle.offset;
htype = tcf_pedit_htype(a, i);
cmd = tcf_pedit_cmd(a, i);
mask = tcf_pedit_mask(a, i);
offset = tcf_pedit_offset(a, i);
if (cmd != TCA_PEDIT_KEY_EX_CMD_SET) {
netdev_err(dev, "%s: Unsupported pedit cmd\n",
__func__);
return false;
}
switch (htype) { switch (htype) {
case TCA_PEDIT_KEY_EX_HDR_TYPE_ETH: case FLOW_ACT_MANGLE_HDR_TYPE_ETH:
switch (offset) { switch (offset) {
case PEDIT_ETH_DMAC_31_0: case PEDIT_ETH_DMAC_31_0:
case PEDIT_ETH_DMAC_47_32_SMAC_15_0: case PEDIT_ETH_DMAC_47_32_SMAC_15_0:
...@@ -480,7 +477,7 @@ static bool valid_pedit_action(struct net_device *dev, ...@@ -480,7 +477,7 @@ static bool valid_pedit_action(struct net_device *dev,
return false; return false;
} }
break; break;
case TCA_PEDIT_KEY_EX_HDR_TYPE_IP4: case FLOW_ACT_MANGLE_HDR_TYPE_IP4:
switch (offset) { switch (offset) {
case PEDIT_IP4_SRC: case PEDIT_IP4_SRC:
case PEDIT_IP4_DST: case PEDIT_IP4_DST:
...@@ -491,7 +488,7 @@ static bool valid_pedit_action(struct net_device *dev, ...@@ -491,7 +488,7 @@ static bool valid_pedit_action(struct net_device *dev,
return false; return false;
} }
break; break;
case TCA_PEDIT_KEY_EX_HDR_TYPE_IP6: case FLOW_ACT_MANGLE_HDR_TYPE_IP6:
switch (offset) { switch (offset) {
case PEDIT_IP6_SRC_31_0: case PEDIT_IP6_SRC_31_0:
case PEDIT_IP6_SRC_63_32: case PEDIT_IP6_SRC_63_32:
...@@ -508,7 +505,7 @@ static bool valid_pedit_action(struct net_device *dev, ...@@ -508,7 +505,7 @@ static bool valid_pedit_action(struct net_device *dev,
return false; return false;
} }
break; break;
case TCA_PEDIT_KEY_EX_HDR_TYPE_TCP: case FLOW_ACT_MANGLE_HDR_TYPE_TCP:
switch (offset) { switch (offset) {
case PEDIT_TCP_SPORT_DPORT: case PEDIT_TCP_SPORT_DPORT:
if (!valid_l4_mask(~mask)) { if (!valid_l4_mask(~mask)) {
...@@ -523,7 +520,7 @@ static bool valid_pedit_action(struct net_device *dev, ...@@ -523,7 +520,7 @@ static bool valid_pedit_action(struct net_device *dev,
return false; return false;
} }
break; break;
case TCA_PEDIT_KEY_EX_HDR_TYPE_UDP: case FLOW_ACT_MANGLE_HDR_TYPE_UDP:
switch (offset) { switch (offset) {
case PEDIT_UDP_SPORT_DPORT: case PEDIT_UDP_SPORT_DPORT:
if (!valid_l4_mask(~mask)) { if (!valid_l4_mask(~mask)) {
...@@ -539,35 +536,35 @@ static bool valid_pedit_action(struct net_device *dev, ...@@ -539,35 +536,35 @@ static bool valid_pedit_action(struct net_device *dev,
} }
break; break;
default: default:
netdev_err(dev, "%s: Unsupported pedit type\n", netdev_err(dev, "%s: Unsupported pedit type\n", __func__);
__func__);
return false; return false;
} }
}
return true; return true;
} }
static int cxgb4_validate_flow_actions(struct net_device *dev, static int cxgb4_validate_flow_actions(struct net_device *dev,
struct tc_cls_flower_offload *cls) struct tc_cls_flower_offload *cls)
{ {
const struct tc_action *a; struct flow_rule *rule = tc_cls_flower_offload_flow_rule(cls);
struct flow_action_entry *act;
bool act_redir = false; bool act_redir = false;
bool act_pedit = false; bool act_pedit = false;
bool act_vlan = false; bool act_vlan = false;
int i; int i;
tcf_exts_for_each_action(i, a, cls->exts) { flow_action_for_each(i, act, &rule->action) {
if (is_tcf_gact_ok(a)) { switch (act->id) {
case FLOW_ACTION_ACCEPT:
case FLOW_ACTION_DROP:
/* Do nothing */ /* Do nothing */
} else if (is_tcf_gact_shot(a)) { break;
/* Do nothing */ case FLOW_ACTION_REDIRECT: {
} else if (is_tcf_mirred_egress_redirect(a)) {
struct adapter *adap = netdev2adap(dev); struct adapter *adap = netdev2adap(dev);
struct net_device *n_dev, *target_dev; struct net_device *n_dev, *target_dev;
unsigned int i; unsigned int i;
bool found = false; bool found = false;
target_dev = tcf_mirred_dev(a); target_dev = act->dev;
for_each_port(adap, i) { for_each_port(adap, i) {
n_dev = adap->port[i]; n_dev = adap->port[i];
if (target_dev == n_dev) { if (target_dev == n_dev) {
...@@ -585,15 +582,18 @@ static int cxgb4_validate_flow_actions(struct net_device *dev, ...@@ -585,15 +582,18 @@ static int cxgb4_validate_flow_actions(struct net_device *dev,
return -EINVAL; return -EINVAL;
} }
act_redir = true; act_redir = true;
} else if (is_tcf_vlan(a)) { }
u16 proto = be16_to_cpu(tcf_vlan_push_proto(a)); break;
u32 vlan_action = tcf_vlan_action(a); case FLOW_ACTION_VLAN_POP:
case FLOW_ACTION_VLAN_PUSH:
case FLOW_ACTION_VLAN_MANGLE: {
u16 proto = be16_to_cpu(act->vlan.proto);
switch (vlan_action) { switch (act->id) {
case TCA_VLAN_ACT_POP: case FLOW_ACTION_VLAN_POP:
break; break;
case TCA_VLAN_ACT_PUSH: case FLOW_ACTION_VLAN_PUSH:
case TCA_VLAN_ACT_MODIFY: case FLOW_ACTION_VLAN_MANGLE:
if (proto != ETH_P_8021Q) { if (proto != ETH_P_8021Q) {
netdev_err(dev, "%s: Unsupported vlan proto\n", netdev_err(dev, "%s: Unsupported vlan proto\n",
__func__); __func__);
...@@ -606,13 +606,17 @@ static int cxgb4_validate_flow_actions(struct net_device *dev, ...@@ -606,13 +606,17 @@ static int cxgb4_validate_flow_actions(struct net_device *dev,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
act_vlan = true; act_vlan = true;
} else if (is_tcf_pedit(a)) { }
bool pedit_valid = valid_pedit_action(dev, a); break;
case FLOW_ACTION_MANGLE: {
bool pedit_valid = valid_pedit_action(dev, act);
if (!pedit_valid) if (!pedit_valid)
return -EOPNOTSUPP; return -EOPNOTSUPP;
act_pedit = true; act_pedit = true;
} else { }
break;
default:
netdev_err(dev, "%s: Unsupported action\n", __func__); netdev_err(dev, "%s: Unsupported action\n", __func__);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
......
...@@ -588,7 +588,7 @@ int mlxsw_sp_acl_rulei_act_vlan(struct mlxsw_sp *mlxsw_sp, ...@@ -588,7 +588,7 @@ int mlxsw_sp_acl_rulei_act_vlan(struct mlxsw_sp *mlxsw_sp,
{ {
u8 ethertype; u8 ethertype;
if (action == TCA_VLAN_ACT_MODIFY) { if (action == FLOW_ACTION_VLAN_MANGLE) {
switch (proto) { switch (proto) {
case ETH_P_8021Q: case ETH_P_8021Q:
ethertype = 0; ethertype = 0;
......
...@@ -17,13 +17,13 @@ ...@@ -17,13 +17,13 @@
static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp, static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_block *block, struct mlxsw_sp_acl_block *block,
struct mlxsw_sp_acl_rule_info *rulei, struct mlxsw_sp_acl_rule_info *rulei,
struct tcf_exts *exts, struct flow_action *flow_action,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
const struct tc_action *a; const struct flow_action_entry *act;
int err, i; int err, i;
if (!tcf_exts_has_actions(exts)) if (!flow_action_has_entries(flow_action))
return 0; return 0;
/* Count action is inserted first */ /* Count action is inserted first */
...@@ -31,27 +31,31 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp, ...@@ -31,27 +31,31 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
if (err) if (err)
return err; return err;
tcf_exts_for_each_action(i, a, exts) { flow_action_for_each(i, act, flow_action) {
if (is_tcf_gact_ok(a)) { switch (act->id) {
case FLOW_ACTION_ACCEPT:
err = mlxsw_sp_acl_rulei_act_terminate(rulei); err = mlxsw_sp_acl_rulei_act_terminate(rulei);
if (err) { if (err) {
NL_SET_ERR_MSG_MOD(extack, "Cannot append terminate action"); NL_SET_ERR_MSG_MOD(extack, "Cannot append terminate action");
return err; return err;
} }
} else if (is_tcf_gact_shot(a)) { break;
case FLOW_ACTION_DROP:
err = mlxsw_sp_acl_rulei_act_drop(rulei); err = mlxsw_sp_acl_rulei_act_drop(rulei);
if (err) { if (err) {
NL_SET_ERR_MSG_MOD(extack, "Cannot append drop action"); NL_SET_ERR_MSG_MOD(extack, "Cannot append drop action");
return err; return err;
} }
} else if (is_tcf_gact_trap(a)) { break;
case FLOW_ACTION_TRAP:
err = mlxsw_sp_acl_rulei_act_trap(rulei); err = mlxsw_sp_acl_rulei_act_trap(rulei);
if (err) { if (err) {
NL_SET_ERR_MSG_MOD(extack, "Cannot append trap action"); NL_SET_ERR_MSG_MOD(extack, "Cannot append trap action");
return err; return err;
} }
} else if (is_tcf_gact_goto_chain(a)) { break;
u32 chain_index = tcf_gact_goto_chain_index(a); case FLOW_ACTION_GOTO: {
u32 chain_index = act->chain_index;
struct mlxsw_sp_acl_ruleset *ruleset; struct mlxsw_sp_acl_ruleset *ruleset;
u16 group_id; u16 group_id;
...@@ -67,7 +71,9 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp, ...@@ -67,7 +71,9 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
NL_SET_ERR_MSG_MOD(extack, "Cannot append jump action"); NL_SET_ERR_MSG_MOD(extack, "Cannot append jump action");
return err; return err;
} }
} else if (is_tcf_mirred_egress_redirect(a)) { }
break;
case FLOW_ACTION_REDIRECT: {
struct net_device *out_dev; struct net_device *out_dev;
struct mlxsw_sp_fid *fid; struct mlxsw_sp_fid *fid;
u16 fid_index; u16 fid_index;
...@@ -79,29 +85,34 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp, ...@@ -79,29 +85,34 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
if (err) if (err)
return err; return err;
out_dev = tcf_mirred_dev(a); out_dev = act->dev;
err = mlxsw_sp_acl_rulei_act_fwd(mlxsw_sp, rulei, err = mlxsw_sp_acl_rulei_act_fwd(mlxsw_sp, rulei,
out_dev, extack); out_dev, extack);
if (err) if (err)
return err; return err;
} else if (is_tcf_mirred_egress_mirror(a)) { }
struct net_device *out_dev = tcf_mirred_dev(a); break;
case FLOW_ACTION_MIRRED: {
struct net_device *out_dev = act->dev;
err = mlxsw_sp_acl_rulei_act_mirror(mlxsw_sp, rulei, err = mlxsw_sp_acl_rulei_act_mirror(mlxsw_sp, rulei,
block, out_dev, block, out_dev,
extack); extack);
if (err) if (err)
return err; return err;
} else if (is_tcf_vlan(a)) { }
u16 proto = be16_to_cpu(tcf_vlan_push_proto(a)); break;
u32 action = tcf_vlan_action(a); case FLOW_ACTION_VLAN_PUSH:
u8 prio = tcf_vlan_push_prio(a); case FLOW_ACTION_VLAN_POP: {
u16 vid = tcf_vlan_push_vid(a); u16 proto = be16_to_cpu(act->vlan.proto);
u8 prio = act->vlan.prio;
u16 vid = act->vlan.vid;
return mlxsw_sp_acl_rulei_act_vlan(mlxsw_sp, rulei, return mlxsw_sp_acl_rulei_act_vlan(mlxsw_sp, rulei,
action, vid, act->id, vid,
proto, prio, extack); proto, prio, extack);
} else { }
default:
NL_SET_ERR_MSG_MOD(extack, "Unsupported action"); NL_SET_ERR_MSG_MOD(extack, "Unsupported action");
dev_err(mlxsw_sp->bus_info->dev, "Unsupported action\n"); dev_err(mlxsw_sp->bus_info->dev, "Unsupported action\n");
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -361,7 +372,8 @@ static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp, ...@@ -361,7 +372,8 @@ static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp,
if (err) if (err)
return err; return err;
return mlxsw_sp_flower_parse_actions(mlxsw_sp, block, rulei, f->exts, return mlxsw_sp_flower_parse_actions(mlxsw_sp, block, rulei,
&f->rule->action,
f->common.extack); f->common.extack);
} }
......
...@@ -2004,21 +2004,21 @@ int qede_get_arfs_filter_count(struct qede_dev *edev) ...@@ -2004,21 +2004,21 @@ int qede_get_arfs_filter_count(struct qede_dev *edev)
} }
static int qede_parse_actions(struct qede_dev *edev, static int qede_parse_actions(struct qede_dev *edev,
struct tcf_exts *exts) struct flow_action *flow_action)
{ {
const struct flow_action_entry *act;
int rc = -EINVAL, num_act = 0, i; int rc = -EINVAL, num_act = 0, i;
const struct tc_action *a;
bool is_drop = false; bool is_drop = false;
if (!tcf_exts_has_actions(exts)) { if (!flow_action_has_entries(flow_action)) {
DP_NOTICE(edev, "No tc actions received\n"); DP_NOTICE(edev, "No tc actions received\n");
return rc; return rc;
} }
tcf_exts_for_each_action(i, a, exts) { flow_action_for_each(i, act, flow_action) {
num_act++; num_act++;
if (is_tcf_gact_shot(a)) if (act->id == FLOW_ACTION_DROP)
is_drop = true; is_drop = true;
} }
...@@ -2235,7 +2235,7 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto, ...@@ -2235,7 +2235,7 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto,
} }
/* parse tc actions and get the vf_id */ /* parse tc actions and get the vf_id */
if (qede_parse_actions(edev, f->exts)) if (qede_parse_actions(edev, &f->rule->action))
goto unlock; goto unlock;
if (qede_flow_find_fltr(edev, &t)) { if (qede_flow_find_fltr(edev, &t)) {
......
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