Add support for offloading multiple remote destinations by parsing the actions and adding remote destinations actions. Update dump_flow_action in order to support tunnel actions.
Co-authored-by: Salem Sol <[email protected]> Signed-off-by: Noa Levy <[email protected]> Signed-off-by: Salem Sol <[email protected]> --- NEWS | 3 +- lib/netdev-offload-dpdk.c | 69 ++++++++++++++++++++++++++++++--------- 2 files changed, 55 insertions(+), 17 deletions(-) diff --git a/NEWS b/NEWS index 066f90437..d2f0b8812 100644 --- a/NEWS +++ b/NEWS @@ -12,7 +12,8 @@ Post-v2.15.0 - DPDK: * OVS validated with DPDK 20.11.1. It is recommended to use this version until further releases. - * Add support for offloading multiple local destinations actions. + * Add support for offloading multiple local and remote destinations + actions. v2.15.0 - 15 Feb 2021 --------------------- diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index eb798a69b..ab30fbbeb 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -630,6 +630,13 @@ dump_flow_action(struct ds *s, struct ds *s_extra, rte_actions->type != RTE_FLOW_ACTION_TYPE_END) { if (rte_actions->type == RTE_FLOW_ACTION_TYPE_PORT_ID) { dump_port_id(s_extra, rte_actions->conf); + } else if (rte_actions->type == + RTE_FLOW_ACTION_TYPE_RAW_ENCAP) { + const struct rte_flow_action_raw_encap *raw_encap = + rte_actions->conf; + + dump_raw_encap(s, s_extra, raw_encap); + ds_put_format(s_extra, "raw_encap index 0 / "); } else { ds_put_format(s, "unknown rte flow action (%d)\n", rte_actions->type); @@ -1744,37 +1751,53 @@ parse_clone_actions(struct netdev *netdev, } /* Maximum number of actions in multiple local destinations. - * PORT_ID / END + * RAW_ENCAP / PORT_ID / END */ -#define SAMPLE_EMBEDDED_ACTIONS_NUM 2 +#define SAMPLE_EMBEDDED_ACTIONS_NUM 3 static int add_sample_embedded_output_action(struct netdev *netdev, struct flow_actions *actions, - const struct nlattr *nla) + const struct nlattr *nla, + const size_t clone_actions_len) { struct netdev *outdev; struct sample_conf { struct rte_flow_action_sample sample; struct rte_flow_action_port_id port_id; + struct rte_flow_action_raw_encap raw_encap; struct rte_flow_action sample_actions[SAMPLE_EMBEDDED_ACTIONS_NUM]; } *sample_conf; BUILD_ASSERT_DECL(offsetof(struct sample_conf, sample) == 0); struct rte_flow_action *sample_itr; + bool is_raw; int port_id; - if (get_netdev_by_port(netdev, nla, &port_id, &outdev)) { - return -1; - } - netdev_close(outdev); - sample_conf = xzalloc(sizeof *sample_conf); sample_itr = sample_conf->sample_actions; + is_raw = false; + if (!clone_actions_len) { + if (get_netdev_by_port(netdev, nla, &port_id, &outdev)) { + goto err; + } + netdev_close(outdev); + } else { + if (parse_clone_actions(netdev, NULL, nla, + clone_actions_len, &port_id, + &sample_conf->raw_encap)) { + goto err; + } + is_raw = sample_conf->raw_encap.size > 0; + } /* Initialize sample struct */ sample_conf->sample.ratio = 1; sample_conf->sample.actions = sample_conf->sample_actions; sample_conf->port_id.id = port_id; - + if (is_raw) { + sample_itr->conf = &sample_conf->raw_encap; + sample_itr->type = RTE_FLOW_ACTION_TYPE_RAW_ENCAP; + sample_itr++; + } sample_itr->conf = &sample_conf->port_id; sample_itr->type = RTE_FLOW_ACTION_TYPE_PORT_ID; sample_itr++; @@ -1782,6 +1805,9 @@ add_sample_embedded_output_action(struct netdev *netdev, add_flow_action(actions, RTE_FLOW_ACTION_TYPE_SAMPLE, sample_conf); return 0; +err: + free(sample_conf); + return -1; } static void @@ -1857,7 +1883,8 @@ parse_flow_actions(struct netdev *netdev, return -1; } } else { - if (add_sample_embedded_output_action(netdev, actions, nla)) { + if (add_sample_embedded_output_action(netdev, actions, nla, + 0)) { return -1; } } @@ -1881,14 +1908,24 @@ parse_flow_actions(struct netdev *netdev, } } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_POP_VLAN) { add_flow_action(actions, RTE_FLOW_ACTION_TYPE_OF_POP_VLAN, NULL); - } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_CLONE && - left <= NLA_ALIGN(nla->nla_len)) { + } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_CLONE) { const struct nlattr *clone_actions = nl_attr_get(nla); size_t clone_actions_len = nl_attr_get_size(nla); - - if (parse_clone_actions(netdev, actions, clone_actions, - clone_actions_len, NULL, NULL)) { - return -1; + /* The last cloned action is parsed and actions are applied + * natively, while previous ones are parsed and the actions are + * applied embedded in a sample action. + */ + if (left <= NLA_ALIGN(nla->nla_len)) { + if (parse_clone_actions(netdev, actions, clone_actions, + clone_actions_len, NULL, NULL)) { + return -1; + } + } else { + if (add_sample_embedded_output_action(netdev, actions, + clone_actions, + clone_actions_len)) { + return -1; + } } } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_TUNNEL_POP) { if (add_tnl_pop_action(netdev, actions, nla)) { -- 2.28.0.2311.g225365fb51 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
