Refactor the flow action calculate function, break the big function with a long 'switch' control statement into a array of small functions, which makes the logic more clear and easy to reuse.
Signed-off-by: Chaoyong He <chaoyong...@corigine.com> Reviewed-by: Long Wu <long...@corigine.com> Reviewed-by: Peng Zhang <peng.zh...@corigine.com> --- drivers/net/nfp/flower/nfp_flower_flow.c | 361 +++++++++++++---------- 1 file changed, 199 insertions(+), 162 deletions(-) diff --git a/drivers/net/nfp/flower/nfp_flower_flow.c b/drivers/net/nfp/flower/nfp_flower_flow.c index 9717af9c9c..9477e4a94f 100644 --- a/drivers/net/nfp/flower/nfp_flower_flow.c +++ b/drivers/net/nfp/flower/nfp_flower_flow.c @@ -984,184 +984,221 @@ struct nfp_action_flag { bool ttl_tos_flag; }; +struct nfp_action_calculate_param { + const struct rte_flow_action *action; + struct nfp_fl_key_ls *key_ls; + struct nfp_action_flag *flag; +}; + +typedef int (*nfp_flow_key_calculate_action_fn)(struct nfp_action_calculate_param *param); + +static int +nfp_flow_action_calculate_stub(struct nfp_action_calculate_param *param __rte_unused) +{ + return 0; +} + +static int +nfp_flow_action_calculate_port(struct nfp_action_calculate_param *param) +{ + param->key_ls->act_size += sizeof(struct nfp_fl_act_output); + + return 0; +} + +static int +nfp_flow_action_calculate_mac(struct nfp_action_calculate_param *param) +{ + if (!param->flag->mac_set_flag) { + param->key_ls->act_size += sizeof(struct nfp_fl_act_set_eth); + param->flag->mac_set_flag = true; + } + + return 0; +} + +static int +nfp_flow_action_calculate_pop_vlan(struct nfp_action_calculate_param *param) +{ + param->key_ls->act_size += sizeof(struct nfp_fl_act_pop_vlan); + + return 0; +} + +static int +nfp_flow_action_calculate_push_vlan(struct nfp_action_calculate_param *param) +{ + param->key_ls->act_size += sizeof(struct nfp_fl_act_push_vlan); + + return 0; +} + +static int +nfp_flow_action_calculate_ipv4_addr(struct nfp_action_calculate_param *param) +{ + if (!param->flag->ip_set_flag) { + param->key_ls->act_size += sizeof(struct nfp_fl_act_set_ip4_addrs); + param->flag->ip_set_flag = true; + } + + return 0; +} + +static int +nfp_flow_action_calculate_ipv6_addr(struct nfp_action_calculate_param *param) +{ + param->key_ls->act_size += sizeof(struct nfp_fl_act_set_ipv6_addr); + + return 0; +} + +static int +nfp_flow_action_calculate_tp(struct nfp_action_calculate_param *param) +{ + if (!param->flag->tp_set_flag) { + param->key_ls->act_size += sizeof(struct nfp_fl_act_set_tport); + param->flag->tp_set_flag = true; + } + + return 0; +} + +static int +nfp_flow_action_calculate_ttl(struct nfp_action_calculate_param *param) +{ + if ((param->key_ls->key_layer & NFP_FLOWER_LAYER_IPV4) != 0) { + if (!param->flag->ttl_tos_flag) { + param->key_ls->act_size += sizeof(struct nfp_fl_act_set_ip4_ttl_tos); + param->flag->ttl_tos_flag = true; + } + } else { + if (!param->flag->tc_hl_flag) { + param->key_ls->act_size += sizeof(struct nfp_fl_act_set_ipv6_tc_hl_fl); + param->flag->tc_hl_flag = true; + } + } + + return 0; +} + +static int +nfp_flow_action_calculate_ipv4_dscp(struct nfp_action_calculate_param *param) +{ + if (!param->flag->ttl_tos_flag) { + param->key_ls->act_size += sizeof(struct nfp_fl_act_set_ip4_ttl_tos); + param->flag->ttl_tos_flag = true; + } + + return 0; +} + +static int +nfp_flow_action_calculate_ipv6_dscp(struct nfp_action_calculate_param *param) +{ + if (!param->flag->tc_hl_flag) { + param->key_ls->act_size += sizeof(struct nfp_fl_act_set_ipv6_tc_hl_fl); + param->flag->tc_hl_flag = true; + } + + return 0; +} + +static int +nfp_flow_action_calculate_encap(struct nfp_action_calculate_param *param) +{ + param->key_ls->act_size += sizeof(struct nfp_fl_act_pre_tun); + param->key_ls->act_size += sizeof(struct nfp_fl_act_set_tun); + + return 0; +} + +static int +nfp_flow_action_calculate_meter(struct nfp_action_calculate_param *param) +{ + if (param->flag->meter_flag) { + PMD_DRV_LOG(ERR, "Only support one meter action."); + return -ENOTSUP; + } + + param->key_ls->act_size += sizeof(struct nfp_fl_act_meter); + param->flag->meter_flag = true; + + return 0; +} + +static int +nfp_flow_action_calculate_mark(struct nfp_action_calculate_param *param) +{ + param->key_ls->act_size += sizeof(struct nfp_fl_act_mark); + + return 0; +} + +static nfp_flow_key_calculate_action_fn action_fns[] = { + [RTE_FLOW_ACTION_TYPE_VOID] = nfp_flow_action_calculate_stub, + [RTE_FLOW_ACTION_TYPE_DROP] = nfp_flow_action_calculate_stub, + [RTE_FLOW_ACTION_TYPE_COUNT] = nfp_flow_action_calculate_stub, + [RTE_FLOW_ACTION_TYPE_JUMP] = nfp_flow_action_calculate_stub, + [RTE_FLOW_ACTION_TYPE_PORT_ID] = nfp_flow_action_calculate_port, + [RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT] = nfp_flow_action_calculate_port, + [RTE_FLOW_ACTION_TYPE_SET_MAC_SRC] = nfp_flow_action_calculate_mac, + [RTE_FLOW_ACTION_TYPE_SET_MAC_DST] = nfp_flow_action_calculate_mac, + [RTE_FLOW_ACTION_TYPE_OF_POP_VLAN] = nfp_flow_action_calculate_pop_vlan, + [RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN] = nfp_flow_action_calculate_push_vlan, + [RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID] = nfp_flow_action_calculate_stub, + [RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP] = nfp_flow_action_calculate_stub, + [RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC] = nfp_flow_action_calculate_ipv4_addr, + [RTE_FLOW_ACTION_TYPE_SET_IPV4_DST] = nfp_flow_action_calculate_ipv4_addr, + [RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC] = nfp_flow_action_calculate_ipv6_addr, + [RTE_FLOW_ACTION_TYPE_SET_IPV6_DST] = nfp_flow_action_calculate_ipv6_addr, + [RTE_FLOW_ACTION_TYPE_SET_TP_SRC] = nfp_flow_action_calculate_tp, + [RTE_FLOW_ACTION_TYPE_SET_TP_DST] = nfp_flow_action_calculate_tp, + [RTE_FLOW_ACTION_TYPE_SET_TTL] = nfp_flow_action_calculate_ttl, + [RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP] = nfp_flow_action_calculate_ipv4_dscp, + [RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP] = nfp_flow_action_calculate_ipv6_dscp, + [RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP] = nfp_flow_action_calculate_encap, + [RTE_FLOW_ACTION_TYPE_RAW_ENCAP] = nfp_flow_action_calculate_encap, + [RTE_FLOW_ACTION_TYPE_VXLAN_DECAP] = nfp_flow_action_calculate_stub, + [RTE_FLOW_ACTION_TYPE_RAW_DECAP] = nfp_flow_action_calculate_stub, + [RTE_FLOW_ACTION_TYPE_METER] = nfp_flow_action_calculate_meter, + [RTE_FLOW_ACTION_TYPE_CONNTRACK] = nfp_flow_action_calculate_stub, + [RTE_FLOW_ACTION_TYPE_MARK] = nfp_flow_action_calculate_mark, + [RTE_FLOW_ACTION_TYPE_RSS] = nfp_flow_action_calculate_stub, +}; + static int nfp_flow_key_layers_calculate_actions(const struct rte_flow_action actions[], struct nfp_fl_key_ls *key_ls) { - int ret = 0; + int ret; struct nfp_action_flag flag = {}; const struct rte_flow_action *action; + struct nfp_action_calculate_param param = { + .key_ls = key_ls, + .flag = &flag, + }; for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) { /* Make sure actions length no longer than NFP_FL_MAX_A_SIZ */ if (key_ls->act_size > NFP_FL_MAX_A_SIZ) { PMD_DRV_LOG(ERR, "The action list is too long."); - ret = -ERANGE; - break; + return -EINVAL; } - switch (action->type) { - case RTE_FLOW_ACTION_TYPE_VOID: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_VOID detected"); - break; - case RTE_FLOW_ACTION_TYPE_DROP: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_DROP detected"); - break; - case RTE_FLOW_ACTION_TYPE_COUNT: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_COUNT detected"); - break; - case RTE_FLOW_ACTION_TYPE_JUMP: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_JUMP detected"); - break; - case RTE_FLOW_ACTION_TYPE_PORT_ID: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_PORT_ID detected"); - key_ls->act_size += sizeof(struct nfp_fl_act_output); - break; - case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT detected"); - key_ls->act_size += sizeof(struct nfp_fl_act_output); - break; - case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_MAC_SRC detected"); - if (!flag.mac_set_flag) { - key_ls->act_size += sizeof(struct nfp_fl_act_set_eth); - flag.mac_set_flag = true; - } - break; - case RTE_FLOW_ACTION_TYPE_SET_MAC_DST: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_MAC_DST detected"); - if (!flag.mac_set_flag) { - key_ls->act_size += sizeof(struct nfp_fl_act_set_eth); - flag.mac_set_flag = true; - } - break; - case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_OF_POP_VLAN detected"); - key_ls->act_size += sizeof(struct nfp_fl_act_pop_vlan); - break; - case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN detected"); - key_ls->act_size += sizeof(struct nfp_fl_act_push_vlan); - break; - case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID detected"); - break; - case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP detected"); - break; - case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC detected"); - if (!flag.ip_set_flag) { - key_ls->act_size += - sizeof(struct nfp_fl_act_set_ip4_addrs); - flag.ip_set_flag = true; - } - break; - case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV4_DST detected"); - if (!flag.ip_set_flag) { - key_ls->act_size += - sizeof(struct nfp_fl_act_set_ip4_addrs); - flag.ip_set_flag = true; - } - break; - case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC detected"); - key_ls->act_size += sizeof(struct nfp_fl_act_set_ipv6_addr); - break; - case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV6_DST detected"); - key_ls->act_size += sizeof(struct nfp_fl_act_set_ipv6_addr); - break; - case RTE_FLOW_ACTION_TYPE_SET_TP_SRC: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_TP_SRC detected"); - if (!flag.tp_set_flag) { - key_ls->act_size += sizeof(struct nfp_fl_act_set_tport); - flag.tp_set_flag = true; - } - break; - case RTE_FLOW_ACTION_TYPE_SET_TP_DST: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_TP_DST detected"); - if (!flag.tp_set_flag) { - key_ls->act_size += sizeof(struct nfp_fl_act_set_tport); - flag.tp_set_flag = true; - } - break; - case RTE_FLOW_ACTION_TYPE_SET_TTL: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_TTL detected"); - if ((key_ls->key_layer & NFP_FLOWER_LAYER_IPV4) != 0) { - if (!flag.ttl_tos_flag) { - key_ls->act_size += - sizeof(struct nfp_fl_act_set_ip4_ttl_tos); - flag.ttl_tos_flag = true; - } - } else { - if (!flag.tc_hl_flag) { - key_ls->act_size += - sizeof(struct nfp_fl_act_set_ipv6_tc_hl_fl); - flag.tc_hl_flag = true; - } - } - break; - case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP detected"); - if (!flag.ttl_tos_flag) { - key_ls->act_size += - sizeof(struct nfp_fl_act_set_ip4_ttl_tos); - flag.ttl_tos_flag = true; - } - break; - case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP detected"); - if (!flag.tc_hl_flag) { - key_ls->act_size += - sizeof(struct nfp_fl_act_set_ipv6_tc_hl_fl); - flag.tc_hl_flag = true; - } - break; - case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP detected"); - key_ls->act_size += sizeof(struct nfp_fl_act_pre_tun); - key_ls->act_size += sizeof(struct nfp_fl_act_set_tun); - break; - case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_RAW_ENCAP detected"); - key_ls->act_size += sizeof(struct nfp_fl_act_pre_tun); - key_ls->act_size += sizeof(struct nfp_fl_act_set_tun); - break; - case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_VXLAN_DECAP detected"); - break; - case RTE_FLOW_ACTION_TYPE_RAW_DECAP: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_RAW_DECAP detected"); - break; - case RTE_FLOW_ACTION_TYPE_METER: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_METER detected"); - if (!flag.meter_flag) { - key_ls->act_size += sizeof(struct nfp_fl_act_meter); - flag.meter_flag = true; - } else { - PMD_DRV_LOG(ERR, "Only support one meter action."); - return -ENOTSUP; - } - break; - case RTE_FLOW_ACTION_TYPE_CONNTRACK: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_CONNTRACK detected"); - break; - case RTE_FLOW_ACTION_TYPE_MARK: - key_ls->act_size += sizeof(struct nfp_fl_act_mark); - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_MARK detected"); - break; - case RTE_FLOW_ACTION_TYPE_RSS: - PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_RSS detected"); - break; - default: - PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type); - return -ENOTSUP; + if (action->type >= RTE_DIM(action_fns) || action_fns[action->type] == NULL) { + PMD_DRV_LOG(ERR, "Flow action %d unsupported", action->type); + return -ERANGE; + } + + param.action = action; + ret = action_fns[action->type](¶m); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Flow action %d calculate fail", action->type); + return ret; } } - return ret; + return 0; } static int -- 2.39.1