ovs_u128 ufid;
struct netdev *netdev;
struct rte_flow *rte_flow;
@@ -88,7 +86,6 @@ struct ufid_to_rte_flow_data {
struct dpdk_offload_netdev_data {
struct cmap ufid_to_rte_flow;
- struct cmap mark_to_rte_flow;
uint64_t *rte_flow_counters;
struct ovs_mutex map_lock;
};
@@ -242,12 +239,10 @@ offload_data_init(struct netdev *netdev, unsigned int
offload_thread_count)
data = xzalloc(sizeof *data);
ovs_mutex_init(&data->map_lock);
cmap_init(&data->ufid_to_rte_flow);
- cmap_init(&data->mark_to_rte_flow);
data->rte_flow_counters = xcalloc(offload_thread_count,
sizeof *data->rte_flow_counters);
ovsrcu_set(&netdev->hw_info.offload_data, (void *) data);
- atomic_store_relaxed(&netdev->hw_info.post_process_api_supported, true);
return 0;
}
@@ -282,7 +277,6 @@ offload_data_destroy(struct netdev *netdev)
}
cmap_destroy(&data->ufid_to_rte_flow);
- cmap_destroy(&data->mark_to_rte_flow);
ovsrcu_postpone(offload_data_destroy__, data);
ovsrcu_set(&netdev->hw_info.offload_data, NULL);
@@ -327,35 +321,6 @@ offload_data_map(struct netdev *netdev)
return data ? &data->ufid_to_rte_flow : NULL;
}
-static bool
-offload_data_maps(struct netdev *netdev, struct cmap **ufid_map,
- struct cmap **mark_map)
-{
- struct dpdk_offload_netdev_data *data;
-
- data = (struct dpdk_offload_netdev_data *)
- ovsrcu_get(void *, &netdev->hw_info.offload_data);
-
- if (!data) {
- return false;
- }
-
- *ufid_map = &data->ufid_to_rte_flow;
- *mark_map = &data->mark_to_rte_flow;
- return true;
-}
-
-static struct cmap *
-offload_data_mark_map(struct netdev *netdev)
-{
- struct dpdk_offload_netdev_data *data;
-
- data = (struct dpdk_offload_netdev_data *)
- ovsrcu_get(void *, &netdev->hw_info.offload_data);
-
- return data ? &data->mark_to_rte_flow : NULL;
-}
-
/* Find rte_flow with @ufid. */
static struct ufid_to_rte_flow_data *
ufid_to_rte_flow_data_find(struct netdev *netdev, const ovs_u128 *ufid)
@@ -414,26 +379,6 @@ ufid_to_rte_flow_data_find_protected(struct netdev *netdev,
return NULL;
}
-/* Find rte_flow with @flow_mark. */
-static struct ufid_to_rte_flow_data *
-mark_to_rte_flow_data_find(struct netdev *netdev, uint32_t flow_mark)
-{
- size_t hash = hash_int(flow_mark, 0);
- struct ufid_to_rte_flow_data *data;
- struct cmap *mark_map = offload_data_mark_map(netdev);
-
- if (!mark_map) {
- return NULL;
- }
-
- CMAP_FOR_EACH_WITH_HASH (data, mark_node, hash, mark_map) {
- if (data->flow_mark == flow_mark) {
- return data;
- }
- }
- return NULL;
-}
-
static inline struct ufid_to_rte_flow_data *
ufid_to_rte_flow_associate(const ovs_u128 *ufid, struct netdev *netdev,
struct netdev *physdev, struct rte_flow *rte_flow,
@@ -441,11 +386,11 @@ ufid_to_rte_flow_associate(const ovs_u128 *ufid, struct
netdev *netdev,
struct pmd_data *pmd_mapping)
{
size_t hash = hash_bytes(ufid, sizeof *ufid, 0);
+ struct cmap *map = offload_data_map(netdev);
struct ufid_to_rte_flow_data *data_prev;
struct ufid_to_rte_flow_data *data;
- struct cmap *map, *mark_map;
- if (!offload_data_maps(netdev, &map, &mark_map)) {
+ if (!map) {
return NULL;
}
@@ -475,8 +420,6 @@ ufid_to_rte_flow_associate(const ovs_u128 *ufid, struct netdev *netdev,
ovsrcu_set(&data->pmd_mapping, pmd_mapping);
cmap_insert(map, CONST_CAST(struct cmap_node *, &data->node), hash);
- cmap_insert(mark_map, CONST_CAST(struct cmap_node *, &data->mark_node),
- hash_int(flow_mark, 0));
offload_data_unlock(netdev);
return data;
@@ -498,17 +441,15 @@ ufid_to_rte_flow_disassociate(struct
ufid_to_rte_flow_data *data)
OVS_REQUIRES(data->lock)
{
size_t hash = hash_bytes(&data->ufid, sizeof data->ufid, 0);
+ struct cmap *map = offload_data_map(data->netdev);
struct pmd_data *pmd_mapping;
- struct cmap *map, *mark_map;
- if (!offload_data_maps(data->netdev, &map, &mark_map)) {
+ if (!map) {
return;
}
offload_data_lock(data->netdev);
cmap_remove(map, CONST_CAST(struct cmap_node *, &data->node), hash);
- cmap_remove(mark_map, CONST_CAST(struct cmap_node *, &data->mark_node),
- hash_int(data->flow_mark, 0));
offload_data_unlock(data->netdev);
if (data->netdev != data->physdev) {
@@ -533,44 +474,21 @@ struct flow_patterns {
int cnt;
int current_max;
struct netdev *physdev;
- /* tnl_pmd_items is the opaque array of items returned by the PMD. */
- struct rte_flow_item *tnl_pmd_items;
- uint32_t tnl_pmd_items_cnt;
- struct ds s_tnl;
};
struct flow_actions {
struct rte_flow_action *actions;
int cnt;
int current_max;
- struct netdev *tnl_netdev;
- /* tnl_pmd_actions is the opaque array of actions returned by the PMD. */
- struct rte_flow_action *tnl_pmd_actions;
- uint32_t tnl_pmd_actions_cnt;
- /* tnl_pmd_actions_pos is where the tunnel actions starts within the
- * 'actions' field.
- */
- int tnl_pmd_actions_pos;
- struct ds s_tnl;
};
static void
-dump_flow_attr(struct ds *s, struct ds *s_extra,
- const struct rte_flow_attr *attr,
- struct flow_patterns *flow_patterns,
- struct flow_actions *flow_actions)
+dump_flow_attr(struct ds *s, const struct rte_flow_attr *attr)
{
- if (flow_actions->tnl_pmd_actions_cnt) {
- ds_clone(s_extra, &flow_actions->s_tnl);
- } else if (flow_patterns->tnl_pmd_items_cnt) {
- ds_clone(s_extra, &flow_patterns->s_tnl);
- }
- ds_put_format(s, "%s%spriority %"PRIu32" group %"PRIu32" %s%s%s",
+ ds_put_format(s, "%s%spriority %"PRIu32" group %"PRIu32" %s",
attr->ingress ? "ingress " : "",
attr->egress ? "egress " : "", attr->priority,
attr->group,
- attr->transfer ? "transfer " : "",
- flow_actions->tnl_pmd_actions_cnt ? "tunnel_set 1 " : "",
- flow_patterns->tnl_pmd_items_cnt ? "tunnel_match 1 " : "");
+ attr->transfer ? "transfer " : "");
}
/* Adds one pattern item 'field' with the 'mask' to dynamic string 's' using
@@ -596,9 +514,6 @@ dump_flow_pattern(struct ds *s,
if (item->type == RTE_FLOW_ITEM_TYPE_END) {
ds_put_cstr(s, "end ");
- } else if (flow_patterns->tnl_pmd_items_cnt &&
- pattern_index < flow_patterns->tnl_pmd_items_cnt) {
- return;
} else if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
const struct rte_flow_item_eth *eth_spec = item->spec;
const struct rte_flow_item_eth *eth_mask = item->mask;
@@ -974,12 +889,6 @@ dump_flow_action(struct ds *s, struct ds *s_extra,
if (actions->type == RTE_FLOW_ACTION_TYPE_END) {
ds_put_cstr(s, "end");
- } else if (flow_actions->tnl_pmd_actions_cnt &&
- act_index >= flow_actions->tnl_pmd_actions_pos &&
- act_index < flow_actions->tnl_pmd_actions_pos +
- flow_actions->tnl_pmd_actions_cnt) {
- /* Opaque PMD tunnel actions are skipped. */
- return;
} else if (actions->type == RTE_FLOW_ACTION_TYPE_MARK) {
const struct rte_flow_action_mark *mark = actions->conf;
@@ -1137,7 +1046,7 @@ dump_flow(struct ds *s, struct ds *s_extra,
int i;
if (attr) {
- dump_flow_attr(s, s_extra, attr, flow_patterns, flow_actions);
+ dump_flow_attr(s, attr);
}
ds_put_cstr(s, "pattern ");
for (i = 0; i < flow_patterns->cnt; i++) {
@@ -1239,62 +1148,12 @@ add_flow_action(struct flow_actions *actions, enum
rte_flow_action_type type,
actions->cnt++;
}
-static void
-add_flow_tnl_actions(struct flow_actions *actions,
- struct netdev *tnl_netdev,
- struct rte_flow_action *tnl_pmd_actions,
- uint32_t tnl_pmd_actions_cnt)
-{
- int i;
-
- actions->tnl_netdev = tnl_netdev;
- actions->tnl_pmd_actions_pos = actions->cnt;
- actions->tnl_pmd_actions = tnl_pmd_actions;
- actions->tnl_pmd_actions_cnt = tnl_pmd_actions_cnt;
- for (i = 0; i < tnl_pmd_actions_cnt; i++) {
- add_flow_action(actions, tnl_pmd_actions[i].type,
- tnl_pmd_actions[i].conf);
- }
-}
-
-static void
-add_flow_tnl_items(struct flow_patterns *patterns,
- struct netdev *physdev,
- struct rte_flow_item *tnl_pmd_items,
- uint32_t tnl_pmd_items_cnt)
-{
- int i;
-
- patterns->physdev = physdev;
- patterns->tnl_pmd_items = tnl_pmd_items;
- patterns->tnl_pmd_items_cnt = tnl_pmd_items_cnt;
- for (i = 0; i < tnl_pmd_items_cnt; i++) {
- add_flow_pattern(patterns, tnl_pmd_items[i].type,
- tnl_pmd_items[i].spec, tnl_pmd_items[i].mask, NULL);
- }
-}
-
static void
free_flow_patterns(struct flow_patterns *patterns)
{
- struct rte_flow_error error;
int i;
- if (patterns->tnl_pmd_items) {
- struct rte_flow_item *tnl_pmd_items = patterns->tnl_pmd_items;
- uint32_t tnl_pmd_items_cnt = patterns->tnl_pmd_items_cnt;
- struct netdev *physdev = patterns->physdev;
-
- if (netdev_dpdk_rte_flow_tunnel_item_release(physdev, tnl_pmd_items,
- tnl_pmd_items_cnt,
- &error)) {
- VLOG_DBG_RL(&rl, "%s: netdev_dpdk_rte_flow_tunnel_item_release "
- "failed: %d (%s).", netdev_get_name(physdev),
- error.type, error.message);
- }
- }
-
- for (i = patterns->tnl_pmd_items_cnt; i < patterns->cnt; i++) {
+ for (i = 0; i < patterns->cnt; i++) {
if (patterns->items[i].spec) {
free(CONST_CAST(void *, patterns->items[i].spec));
}
@@ -1308,325 +1167,19 @@ free_flow_patterns(struct flow_patterns *patterns)
free(patterns->items);
patterns->items = NULL;
patterns->cnt = 0;
- ds_destroy(&patterns->s_tnl);
}
static void
free_flow_actions(struct flow_actions *actions)
{
- struct rte_flow_error error;
int i;
for (i = 0; i < actions->cnt; i++) {
- if (actions->tnl_pmd_actions_cnt &&
- i == actions->tnl_pmd_actions_pos) {
- if (netdev_dpdk_rte_flow_tunnel_action_decap_release(
- actions->tnl_netdev, actions->tnl_pmd_actions,
- actions->tnl_pmd_actions_cnt, &error)) {
- VLOG_DBG_RL(&rl, "%s: "
- "netdev_dpdk_rte_flow_tunnel_action_decap_release "
- "failed: %d (%s).",
- netdev_get_name(actions->tnl_netdev),
- error.type, error.message);
- }
- i += actions->tnl_pmd_actions_cnt - 1;
- continue;
- }
- if (actions->actions[i].conf) {
- free(CONST_CAST(void *, actions->actions[i].conf));
- }
+ free(CONST_CAST(void *, actions->actions[i].conf));
}
free(actions->actions);
actions->actions = NULL;
actions->cnt = 0;
- ds_destroy(&actions->s_tnl);
-}
-
-static int
-vport_to_rte_tunnel(struct netdev *vport,
- struct rte_flow_tunnel *tunnel,
- struct netdev *netdev,
- struct ds *s_tnl)
-{
- const struct netdev_tunnel_config *tnl_cfg;
-
- memset(tunnel, 0, sizeof *tunnel);
-
- tnl_cfg = netdev_get_tunnel_config(vport);
- if (!tnl_cfg) {
- return -1;
- }
-
- if (!IN6_IS_ADDR_V4MAPPED(&tnl_cfg->ipv6_dst)) {
- tunnel->is_ipv6 = true;
- }
-
- if (!strcmp(netdev_get_type(vport), "vxlan")) {
- tunnel->type = RTE_FLOW_ITEM_TYPE_VXLAN;
- tunnel->tp_dst = tnl_cfg->dst_port;
- if (!VLOG_DROP_DBG(&rl)) {
- ds_put_format(s_tnl, "flow tunnel create %d type vxlan; ",
- netdev_dpdk_get_port_id(netdev));
- }
- } else if (!strcmp(netdev_get_type(vport), "gre")) {
- tunnel->type = RTE_FLOW_ITEM_TYPE_GRE;
- if (!VLOG_DROP_DBG(&rl)) {
- ds_put_format(s_tnl, "flow tunnel create %d type gre; ",
- netdev_dpdk_get_port_id(netdev));
- }
- } else {
- VLOG_DBG_RL(&rl, "vport type '%s' is not supported",
- netdev_get_type(vport));
- return -1;
- }
-
- return 0;
-}
-
-static int
-add_vport_match(struct dpdk_offload *offload,
- struct flow_patterns *patterns,
- odp_port_t orig_in_port,
- struct netdev *tnldev)
-{
- struct rte_flow_item *tnl_pmd_items;
- struct rte_flow_tunnel tunnel;
- struct rte_flow_error error;
- uint32_t tnl_pmd_items_cnt;
- struct netdev *physdev;
- int ret;
-
- physdev = dpdk_offload_get_netdev(offload, orig_in_port);
- if (physdev == NULL) {
- return -1;
- }
-
- ret = vport_to_rte_tunnel(tnldev, &tunnel, physdev, &patterns->s_tnl);
- if (ret) {
- goto out;
- }
- ret = netdev_dpdk_rte_flow_tunnel_match(physdev, &tunnel, &tnl_pmd_items,
- &tnl_pmd_items_cnt, &error);
- if (ret) {
- VLOG_DBG_RL(&rl, "%s: netdev_dpdk_rte_flow_tunnel_match failed: "
- "%d (%s).", netdev_get_name(physdev), error.type,
- error.message);
- goto out;
- }
- add_flow_tnl_items(patterns, physdev, tnl_pmd_items, tnl_pmd_items_cnt);
-
-out:
- return ret;
-}
-
-static int
-parse_tnl_ip_match(struct flow_patterns *patterns,
- struct match *match,
- uint8_t proto)
-{
- struct flow *consumed_masks;
-
- consumed_masks = &match->wc.masks;
- /* IP v4 */
- if (match->wc.masks.tunnel.ip_src || match->wc.masks.tunnel.ip_dst) {
- struct rte_flow_item_ipv4 *spec, *mask;
-
- spec = xzalloc(sizeof *spec);
- mask = xzalloc(sizeof *mask);
-
- spec->hdr.type_of_service = match->flow.tunnel.ip_tos;
- spec->hdr.time_to_live = match->flow.tunnel.ip_ttl;
- spec->hdr.next_proto_id = proto;
- spec->hdr.src_addr = match->flow.tunnel.ip_src;
- spec->hdr.dst_addr = match->flow.tunnel.ip_dst;
-
- mask->hdr.type_of_service = match->wc.masks.tunnel.ip_tos;
- mask->hdr.time_to_live = match->wc.masks.tunnel.ip_ttl;
- mask->hdr.next_proto_id = UINT8_MAX;
- mask->hdr.src_addr = match->wc.masks.tunnel.ip_src;
- mask->hdr.dst_addr = match->wc.masks.tunnel.ip_dst;
-
- consumed_masks->tunnel.ip_tos = 0;
- consumed_masks->tunnel.ip_ttl = 0;
- consumed_masks->tunnel.ip_src = 0;
- consumed_masks->tunnel.ip_dst = 0;
-
- add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_IPV4, spec, mask, NULL);
- } else if (!is_all_zeros(&match->wc.masks.tunnel.ipv6_src,
- sizeof(struct in6_addr)) ||
- !is_all_zeros(&match->wc.masks.tunnel.ipv6_dst,
- sizeof(struct in6_addr))) {
- /* IP v6 */
- struct rte_flow_item_ipv6 *spec, *mask;
-
- spec = xzalloc(sizeof *spec);
- mask = xzalloc(sizeof *mask);
-
- spec->hdr.proto = proto;
- spec->hdr.hop_limits = match->flow.tunnel.ip_ttl;
- spec->hdr.vtc_flow = htonl((uint32_t) match->flow.tunnel.ip_tos <<
- RTE_IPV6_HDR_TC_SHIFT);
- memcpy(&spec->hdr.src_addr, &match->flow.tunnel.ipv6_src,
- sizeof spec->hdr.src_addr);
- memcpy(&spec->hdr.dst_addr, &match->flow.tunnel.ipv6_dst,
- sizeof spec->hdr.dst_addr);
-
- mask->hdr.proto = UINT8_MAX;
- mask->hdr.hop_limits = match->wc.masks.tunnel.ip_ttl;
- mask->hdr.vtc_flow = htonl((uint32_t) match->wc.masks.tunnel.ip_tos <<
- RTE_IPV6_HDR_TC_SHIFT);
- memcpy(&mask->hdr.src_addr, &match->wc.masks.tunnel.ipv6_src,
- sizeof mask->hdr.src_addr);
- memcpy(&mask->hdr.dst_addr, &match->wc.masks.tunnel.ipv6_dst,
- sizeof mask->hdr.dst_addr);
-
- consumed_masks->tunnel.ip_tos = 0;
- consumed_masks->tunnel.ip_ttl = 0;
- memset(&consumed_masks->tunnel.ipv6_src, 0,
- sizeof consumed_masks->tunnel.ipv6_src);
- memset(&consumed_masks->tunnel.ipv6_dst, 0,
- sizeof consumed_masks->tunnel.ipv6_dst);
-
- add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_IPV6, spec, mask, NULL);
- } else {
- VLOG_ERR_RL(&rl, "Tunnel L3 protocol is neither IPv4 nor IPv6");
- return -1;
- }
-
- return 0;
-}
-
-static void
-parse_tnl_udp_match(struct flow_patterns *patterns,
- struct match *match)
-{
- struct flow *consumed_masks;
- struct rte_flow_item_udp *spec, *mask;
-
- consumed_masks = &match->wc.masks;
-
- spec = xzalloc(sizeof *spec);
- mask = xzalloc(sizeof *mask);
-
- spec->hdr.src_port = match->flow.tunnel.tp_src;
- spec->hdr.dst_port = match->flow.tunnel.tp_dst;
-
- mask->hdr.src_port = match->wc.masks.tunnel.tp_src;
- mask->hdr.dst_port = match->wc.masks.tunnel.tp_dst;
-
- consumed_masks->tunnel.tp_src = 0;
- consumed_masks->tunnel.tp_dst = 0;
-
- add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_UDP, spec, mask, NULL);
-}
-
-static int
-parse_vxlan_match(struct flow_patterns *patterns,
- struct match *match)
-{
- struct rte_flow_item_vxlan *vx_spec, *vx_mask;
- struct flow *consumed_masks;
- int ret;
-
- ret = parse_tnl_ip_match(patterns, match, IPPROTO_UDP);
- if (ret) {
- return -1;
- }
- parse_tnl_udp_match(patterns, match);
-
- consumed_masks = &match->wc.masks;
- /* VXLAN */
- vx_spec = xzalloc(sizeof *vx_spec);
- vx_mask = xzalloc(sizeof *vx_mask);
-
- put_16aligned_be32(&ALIGNED_CAST(struct vxlanhdr *, &vx_spec->hdr)->vx_vni,
- htonl(ntohll(match->flow.tunnel.tun_id) << 8));
- put_16aligned_be32(&ALIGNED_CAST(struct vxlanhdr *, &vx_mask->hdr)->vx_vni,
- htonl(ntohll(match->wc.masks.tunnel.tun_id) << 8));
-
- consumed_masks->tunnel.tun_id = 0;
- consumed_masks->tunnel.flags = 0;
-
- add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_VXLAN, vx_spec, vx_mask,
- NULL);
- return 0;
-}
-
-static int
-parse_gre_match(struct flow_patterns *patterns,
- struct match *match)
-{
- struct rte_flow_item_gre *gre_spec, *gre_mask;
- struct rte_gre_hdr *greh_spec, *greh_mask;
- rte_be32_t *key_spec, *key_mask;
- struct flow *consumed_masks;
- int ret;
-
-
- ret = parse_tnl_ip_match(patterns, match, IPPROTO_GRE);
- if (ret) {
- return -1;
- }
-
- gre_spec = xzalloc(sizeof *gre_spec);
- gre_mask = xzalloc(sizeof *gre_mask);
- add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_GRE, gre_spec, gre_mask,
- NULL);
-
- consumed_masks = &match->wc.masks;
-
- greh_spec = (struct rte_gre_hdr *) gre_spec;
- greh_mask = (struct rte_gre_hdr *) gre_mask;
-
- if (match->wc.masks.tunnel.flags & FLOW_TNL_F_CSUM) {
- greh_spec->c = !!(match->flow.tunnel.flags & FLOW_TNL_F_CSUM);
- greh_mask->c = 1;
- consumed_masks->tunnel.flags &= ~FLOW_TNL_F_CSUM;
- }
-
- if (match->wc.masks.tunnel.flags & FLOW_TNL_F_KEY) {
- greh_spec->k = !!(match->flow.tunnel.flags & FLOW_TNL_F_KEY);
- greh_mask->k = 1;
-
- key_spec = xzalloc(sizeof *key_spec);
- key_mask = xzalloc(sizeof *key_mask);
-
- *key_spec = htonl(ntohll(match->flow.tunnel.tun_id));
- *key_mask = htonl(ntohll(match->wc.masks.tunnel.tun_id));
-
- consumed_masks->tunnel.tun_id = 0;
- consumed_masks->tunnel.flags &= ~FLOW_TNL_F_KEY;
- add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_GRE_KEY, key_spec,
- key_mask, NULL);
- }
-
- consumed_masks->tunnel.flags &= ~FLOW_TNL_F_DONT_FRAGMENT;
-
- return 0;
-}
-
-static int OVS_UNUSED
-parse_flow_tnl_match(struct dpdk_offload *offload,
- struct netdev *tnldev,
- struct flow_patterns *patterns,
- odp_port_t orig_in_port,
- struct match *match)
-{
- int ret;
-
- ret = add_vport_match(offload, patterns, orig_in_port, tnldev);
- if (ret) {
- return ret;
- }
-
- if (!strcmp(netdev_get_type(tnldev), "vxlan")) {
- ret = parse_vxlan_match(patterns, match);
- }
- else if (!strcmp(netdev_get_type(tnldev), "gre")) {
- ret = parse_gre_match(patterns, match);
- }
-
- return ret;
}
static int
@@ -1647,12 +1200,6 @@ parse_flow_match(struct dpdk_offload *offload OVS_UNUSED,
}
patterns->physdev = netdev;
-#ifdef ALLOW_EXPERIMENTAL_API /* Packet restoration API required. */
- if (netdev_vport_is_vport_class(netdev->netdev_class) &&
- parse_flow_tnl_match(offload, netdev, patterns, orig_in_port, match)) {
- return -1;
- }
-#endif
memset(&consumed_masks->in_port, 0, sizeof consumed_masks->in_port);
/* recirc id must be zero. */
if (match->wc.masks.recirc_id & match->flow.recirc_id) {
@@ -2021,7 +1568,6 @@ dpdk_offload_mark_rss(struct flow_patterns *patterns,
struct netdev *netdev,
struct flow_actions actions = {
.actions = NULL,
.cnt = 0,
- .s_tnl = DS_EMPTY_INITIALIZER,
};
const struct rte_flow_attr flow_attr = {
.group = 0,
@@ -2393,59 +1939,6 @@ parse_clone_actions(struct dpdk_offload *offload,
return 0;
}
-static void
-add_jump_action(struct flow_actions *actions, uint32_t group)
-{
- struct rte_flow_action_jump *jump = xzalloc (sizeof *jump);
-
- jump->group = group;
- add_flow_action(actions, RTE_FLOW_ACTION_TYPE_JUMP, jump);
-}
-
-static int OVS_UNUSED
-add_tnl_pop_action(struct dpdk_offload *offload,
- struct netdev *netdev,
- struct flow_actions *actions,
- const struct nlattr *nla)
-{
- struct rte_flow_action *tnl_pmd_actions = NULL;
- uint32_t tnl_pmd_actions_cnt = 0;
- struct rte_flow_tunnel tunnel;
- struct rte_flow_error error;
- struct netdev *vport;
- odp_port_t port;
- int ret;
-
- port = nl_attr_get_odp_port(nla);
- vport = dpdk_offload_get_netdev(offload, port);
- if (vport == NULL) {
- return -1;
- }
- ret = vport_to_rte_tunnel(vport, &tunnel, netdev, &actions->s_tnl);
- if (ret) {
- return ret;
- }
- ret = netdev_dpdk_rte_flow_tunnel_decap_set(netdev, &tunnel,
- &tnl_pmd_actions,
- &tnl_pmd_actions_cnt,
- &error);
- if (ret) {
- VLOG_DBG_RL(&rl, "%s: netdev_dpdk_rte_flow_tunnel_decap_set failed: "
- "%d (%s).", netdev_get_name(netdev), error.type,
- error.message);
- return ret;
- }
- add_flow_tnl_actions(actions, netdev, tnl_pmd_actions,
- tnl_pmd_actions_cnt);
- /* After decap_set, the packet processing should continue. In SW, it is
- * done by recirculation (recirc_id = 0). In rte_flow, the group is
- * equivalent to recirc_id, thus jump to group 0 is added to instruct the
- * the HW to proceed processing.
- */
- add_jump_action(actions, 0);
- return 0;
-}
-
static int
parse_flow_actions(struct dpdk_offload *offload,
struct netdev *netdev,
@@ -2493,12 +1986,6 @@ parse_flow_actions(struct dpdk_offload *offload,
clone_actions_len)) {
return -1;
}
-#ifdef ALLOW_EXPERIMENTAL_API /* Packet restoration API required. */
- } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_TUNNEL_POP) {
- if (add_tnl_pop_action(offload, netdev, actions, nla)) {
- return -1;
- }
-#endif
} else {
VLOG_DBG_RL(&rl, "Unsupported action type %d", nl_attr_type(nla));
return -1;
@@ -2525,7 +2012,6 @@ dpdk_offload_with_actions(struct dpdk_offload *offload,
struct flow_actions actions = {
.actions = NULL,
.cnt = 0,
- .s_tnl = DS_EMPTY_INITIALIZER,
};
struct rte_flow *flow = NULL;
struct rte_flow_error error;
@@ -2552,7 +2038,6 @@ dpdk_offload_add_flow(struct dpdk_offload *offload,
struct flow_patterns patterns = {
.items = NULL,
.cnt = 0,
- .s_tnl = DS_EMPTY_INITIALIZER,
};
struct ufid_to_rte_flow_data *flows_data = NULL;
bool actions_offloaded = true;
@@ -2566,7 +2051,7 @@ dpdk_offload_add_flow(struct dpdk_offload *offload,
flow = dpdk_offload_with_actions(offload, patterns.physdev, &patterns,
nl_actions, actions_len);
- if (!flow && !netdev_vport_is_vport_class(netdev->netdev_class)) {
+ if (!flow) {
/* If we failed to offload the rule actions fallback to MARK+RSS
* actions.
*/
@@ -2792,20 +2277,10 @@ int
dpdk_netdev_offload_init(struct netdev *netdev,
unsigned int offload_thread_count)
{
- int ret = EOPNOTSUPP;
-
- if (netdev_vport_is_vport_class(netdev->netdev_class)
- && !strcmp(netdev_get_dpif_type(netdev), "system")) {
- VLOG_DBG("%s: vport belongs to the system datapath. Skipping.",
- netdev_get_name(netdev));
- return EOPNOTSUPP;
- }
-
if (netdev_dpdk_flow_api_supported(netdev, false)) {
- ret = offload_data_init(netdev, offload_thread_count);
+ return offload_data_init(netdev, offload_thread_count);
}
-
- return ret;
+ return EOPNOTSUPP;
}
void
@@ -2893,214 +2368,14 @@ flush_netdev_flows_in_related(struct dpdk_offload
*offload,
}
}
}
-struct flush_in_vport_aux {
- struct dpdk_offload *offload;
- struct netdev *netdev;
-};
-
-static bool
-flush_in_vport_cb(struct netdev *vport,
- odp_port_t odp_port OVS_UNUSED,
- void *aux_)
-{
- struct flush_in_vport_aux *aux = aux_;
-
- /* Only vports are related to physical devices. */
- if (netdev_vport_is_vport_class(vport->netdev_class)) {
- flush_netdev_flows_in_related(aux->offload, aux->netdev, vport);
- }
-
- return false;
-}
int
dpdk_netdev_flow_flush(struct dpdk_offload *offload, struct netdev *netdev)
{
flush_netdev_flows_in_related(offload, netdev, netdev);
-
- if (!netdev_vport_is_vport_class(netdev->netdev_class)) {
- struct flush_in_vport_aux aux = {
- .offload = offload,
- .netdev = netdev
- };
-
- dpdk_offload_traverse_ports(offload, flush_in_vport_cb, &aux);
- }
-
return 0;
}
-struct get_vport_netdev_aux {
- struct rte_flow_tunnel *tunnel;
- odp_port_t *odp_port;
- struct netdev *vport;
- const char *type;
-};
-
-static bool
-get_vport_netdev_cb(struct netdev *netdev,
- odp_port_t odp_port,
- void *aux_)
-{
- const struct netdev_tunnel_config *tnl_cfg;
- struct get_vport_netdev_aux *aux = aux_;
-
- if (!aux->type || strcmp(netdev_get_type(netdev), aux->type)) {
- return false;
- }
- if (!strcmp(netdev_get_type(netdev), "gre")) {
- goto out;
- }
-
- tnl_cfg = netdev_get_tunnel_config(netdev);
- if (!tnl_cfg) {
- VLOG_ERR_RL(&rl, "Cannot get a tunnel config for netdev %s",
- netdev_get_name(netdev));
- return false;
- }
-
- if (tnl_cfg->dst_port != aux->tunnel->tp_dst) {
- return false;
- }
-
-out:
- /* Found the netdev. Store the results and stop the traversing. */
- aux->vport = netdev_ref(netdev);
- *aux->odp_port = odp_port;
-
- return true;
-}
-
-static struct netdev *
-get_vport_netdev(struct dpdk_offload *offload,
- struct rte_flow_tunnel *tunnel,
- odp_port_t *odp_port)
-{
- struct get_vport_netdev_aux aux = {
- .tunnel = tunnel,
- .odp_port = odp_port,
- .vport = NULL,
- .type = NULL,
- };
-
- if (tunnel->type == RTE_FLOW_ITEM_TYPE_VXLAN) {
- aux.type = "vxlan";
- } else if (tunnel->type == RTE_FLOW_ITEM_TYPE_GRE) {
- aux.type = "gre";
- }
- dpdk_offload_traverse_ports(offload, get_vport_netdev_cb, &aux);
-
- return aux.vport;
-}
-
-int
-dpdk_netdev_hw_miss_packet_recover(struct dpdk_offload *offload,
- struct netdev *netdev, unsigned pmd_id,
- struct dp_packet *packet,
- void **flow_reference)
-{
- struct pmd_id_to_flow_ref_data *pmd_data = NULL;
- struct rte_flow_restore_info rte_restore_info;
- struct rte_flow_tunnel *rte_tnl;
- struct netdev *vport_netdev;
- struct pkt_metadata *md;
- struct flow_tnl *md_tnl;
- odp_port_t vport_odp;
- uint32_t flow_mark;
- int ret = 0;
-
- if (dp_packet_has_flow_mark(packet, &flow_mark)) {
- struct ufid_to_rte_flow_data *data;
-
- data = mark_to_rte_flow_data_find(netdev, flow_mark);
- if (data) {
- pmd_data = pmd_data_get(data, pmd_id);
- }
- }
- if (pmd_data) {
- *flow_reference = pmd_data->flow_reference;
- } else {
- *flow_reference = NULL;
- }
-
- ret = netdev_dpdk_rte_flow_get_restore_info(netdev, packet,
- &rte_restore_info, NULL);
- if (ret) {
- if (ret == -EOPNOTSUPP) {
- return -ret;
- }
- /* This function is called for every packet, and in most cases there
- * will be no restore info from the HW, thus error is expected.
- */
- return 0;
- }
-
- if (!(rte_restore_info.flags & RTE_FLOW_RESTORE_INFO_TUNNEL)) {
- return EOPNOTSUPP;
- }
-
- rte_tnl = &rte_restore_info.tunnel;
- vport_netdev = get_vport_netdev(offload, rte_tnl, &vport_odp);
- if (!vport_netdev) {
- VLOG_WARN_RL(&rl, "Could not find vport netdev");
- return EOPNOTSUPP;
- }
-
- md = &packet->md;
- /* For tunnel recovery (RTE_FLOW_RESTORE_INFO_TUNNEL), it is possible
- * to have the packet to still be encapsulated, or not. This is reflected
- * by the RTE_FLOW_RESTORE_INFO_ENCAPSULATED flag.
- * In the case it is on, the packet is still encapsulated, and we do
- * the pop in SW.
- * In the case it is off, the packet is already decapsulated by HW, and
- * the tunnel info is provided in the tunnel struct. For this case we
- * take it to OVS metadata.
- */
- if (rte_restore_info.flags & RTE_FLOW_RESTORE_INFO_ENCAPSULATED) {
- if (!vport_netdev->netdev_class ||
- !vport_netdev->netdev_class->pop_header) {
- VLOG_ERR_RL(&rl, "vport netdev=%s with no pop_header method",
- netdev_get_name(vport_netdev));
- ret = EOPNOTSUPP;
- goto close_vport_netdev;
- }
- parse_tcp_flags(packet, NULL, NULL, NULL);
- if (vport_netdev->netdev_class->pop_header(packet) == NULL) {
- /* If there is an error with popping the header, the packet is
- * freed. In this case it should not continue SW processing.
- */
- ret = EINVAL;
- goto close_vport_netdev;
- }
- } else {
- md_tnl = &md->tunnel;
- if (rte_tnl->is_ipv6) {
- memcpy(&md_tnl->ipv6_src, &rte_tnl->ipv6.src_addr,
- sizeof md_tnl->ipv6_src);
- memcpy(&md_tnl->ipv6_dst, &rte_tnl->ipv6.dst_addr,
- sizeof md_tnl->ipv6_dst);
- } else {
- md_tnl->ip_src = rte_tnl->ipv4.src_addr;
- md_tnl->ip_dst = rte_tnl->ipv4.dst_addr;
- }
- md_tnl->tun_id = htonll(rte_tnl->tun_id);
- md_tnl->flags = rte_tnl->tun_flags;
- md_tnl->ip_tos = rte_tnl->tos;
- md_tnl->ip_ttl = rte_tnl->ttl;
- md_tnl->tp_src = rte_tnl->tp_src;
- }
- /* Change the in_port to the vport's one, in order to continue packet
- * processing in SW.
- */
- md->in_port.odp_port = vport_odp;
- dp_packet_reset_offload(packet);
-
-close_vport_netdev:
- netdev_close(vport_netdev);
-
- return ret;
-}
-
uint64_t
dpdk_netdev_flow_count(struct netdev *netdev,
unsigned int offload_thread_count)
diff --git a/lib/dpif-offload-dpdk-private.h b/lib/dpif-offload-dpdk-private.h
index d5c44f432..5c36a433f 100644
--- a/lib/dpif-offload-dpdk-private.h
+++ b/lib/dpif-offload-dpdk-private.h
@@ -44,9 +44,6 @@ int dpdk_netdev_flow_flush(struct dpdk_offload *, struct
netdev *);
uint64_t dpdk_netdev_flow_count(struct netdev *,
unsigned int offload_thread_count);
uint64_t dpdk_netdev_flow_count_by_thread(struct netdev *, unsigned int tid);
-int dpdk_netdev_hw_miss_packet_recover(struct dpdk_offload *, struct netdev *,
- unsigned pmd_id, struct dp_packet *,
- void **flow_reference);
int dpdk_netdev_flow_put(struct dpdk_offload *, unsigned pmd_id,
void *flow_reference, struct netdev *, struct match
*,
struct nlattr *actions, size_t actions_len,
diff --git a/lib/dpif-offload-dpdk.c b/lib/dpif-offload-dpdk.c
index 2991c24bb..fcf222be4 100644
--- a/lib/dpif-offload-dpdk.c
+++ b/lib/dpif-offload-dpdk.c
@@ -786,10 +786,7 @@ static bool
dpdk_can_offload(struct dpif_offload *offload OVS_UNUSED,
struct netdev *netdev)
{
- if (netdev_vport_is_vport_class(netdev->netdev_class)
- && strcmp(netdev_get_dpif_type(netdev), "netdev")) {
- VLOG_DBG("%s: vport doesn't belong to the netdev datapath, skipping",
- netdev_get_name(netdev));
+ if (netdev_vport_is_vport_class(netdev->netdev_class)) {
return false;
}
@@ -832,17 +829,6 @@ dpdk_flow_count_by_thread(struct dpdk_offload *offload, unsigned int tid)
return total;
}
-static int
-dpdk_offload_hw_post_process(const struct dpif_offload *offload_,
- struct netdev *netdev, unsigned pmd_id,
- struct dp_packet *packet, void **flow_reference)
-{
- struct dpdk_offload *offload = dpdk_offload_cast(offload_);
-
- return dpdk_netdev_hw_miss_packet_recover(offload, netdev, pmd_id, packet,
- flow_reference);
-}
-
static int
dpdk_flow_put(const struct dpif_offload *offload_,
struct netdev *netdev OVS_UNUSED,
@@ -1043,7 +1029,6 @@ struct dpif_offload_class dpif_offload_dpdk_class = {
.port_del = dpdk_offload_port_del,
.flow_count = dpdk_flow_count,
.get_netdev = dpdk_offload_get_netdev__,
- .netdev_hw_post_process = dpdk_offload_hw_post_process,
.netdev_flow_put = dpdk_flow_put,
.netdev_flow_del = dpdk_flow_del,
.netdev_flow_stats = dpdk_flow_stats,
diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index e375275de..60fd93ab9 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -1277,23 +1277,12 @@ dpdk_eth_dev_init_rx_metadata(struct netdev_dpdk *dev)
/* For the fallback offload (non-"transfer" rules). */
rx_metadata |= RTE_ETH_RX_METADATA_USER_MARK;
-#ifdef ALLOW_EXPERIMENTAL_API
- /* For the tunnel offload. */
- rx_metadata |= RTE_ETH_RX_METADATA_TUNNEL_ID;
-#endif /* ALLOW_EXPERIMENTAL_API */
-
ret = rte_eth_rx_metadata_negotiate(dev->port_id, &rx_metadata);
if (ret == 0) {
if (!(rx_metadata & RTE_ETH_RX_METADATA_USER_MARK)) {
VLOG_DBG("%s: The NIC will not provide per-packet USER_MARK",
netdev_get_name(&dev->up));
}
-#ifdef ALLOW_EXPERIMENTAL_API
- if (!(rx_metadata & RTE_ETH_RX_METADATA_TUNNEL_ID)) {
- VLOG_DBG("%s: The NIC will not provide per-packet TUNNEL_ID",
- netdev_get_name(&dev->up));
- }
-#endif /* ALLOW_EXPERIMENTAL_API */
} else {
VLOG(ret == -ENOTSUP ? VLL_DBG : VLL_WARN,
"%s: Cannot negotiate Rx metadata: %s",
@@ -6545,8 +6534,7 @@ netdev_dpdk_flow_api_supported(struct netdev *netdev,
bool check_only)
struct netdev_dpdk *dev;
bool ret = false;
- if ((!strcmp(netdev_get_type(netdev), "vxlan") ||
- !strcmp(netdev_get_type(netdev), "gre")) &&
+ if (!netdev_vport_is_vport_class(netdev->netdev_class) &&
!strcmp(netdev_get_dpif_type(netdev), "netdev")) {
ret = true;
goto out;
@@ -6628,118 +6616,6 @@ netdev_dpdk_rte_flow_query_count(struct netdev *netdev,
return ret;
}
-#ifdef ALLOW_EXPERIMENTAL_API
-
-int
-netdev_dpdk_rte_flow_tunnel_decap_set(struct netdev *netdev,
- struct rte_flow_tunnel *tunnel,
- struct rte_flow_action **actions,
- uint32_t *num_of_actions,
- struct rte_flow_error *error)
-{
- struct netdev_dpdk *dev;
- int ret;
-
- if (!is_dpdk_class(netdev->netdev_class)) {
- return -1;
- }
-
- dev = netdev_dpdk_cast(netdev);
- ovs_mutex_lock(&dev->mutex);
- ret = rte_flow_tunnel_decap_set(dev->port_id, tunnel, actions,
- num_of_actions, error);
- ovs_mutex_unlock(&dev->mutex);
- return ret;
-}
-
-int
-netdev_dpdk_rte_flow_tunnel_match(struct netdev *netdev,
- struct rte_flow_tunnel *tunnel,
- struct rte_flow_item **items,
- uint32_t *num_of_items,
- struct rte_flow_error *error)
-{
- struct netdev_dpdk *dev;
- int ret;
-
- if (!is_dpdk_class(netdev->netdev_class)) {
- return -1;
- }
-
- dev = netdev_dpdk_cast(netdev);
- ovs_mutex_lock(&dev->mutex);
- ret = rte_flow_tunnel_match(dev->port_id, tunnel, items, num_of_items,
- error);
- ovs_mutex_unlock(&dev->mutex);
- return ret;
-}
-
-int
-netdev_dpdk_rte_flow_get_restore_info(struct netdev *netdev,
- struct dp_packet *p,
- struct rte_flow_restore_info *info,
- struct rte_flow_error *error)
-{
- struct rte_mbuf *m = (struct rte_mbuf *) p;
- struct netdev_dpdk *dev;
- int ret;
-
- if (!is_dpdk_class(netdev->netdev_class)) {
- return -1;
- }
-
- dev = netdev_dpdk_cast(netdev);
- ovs_mutex_lock(&dev->mutex);
- ret = rte_flow_get_restore_info(dev->port_id, m, info, error);
- ovs_mutex_unlock(&dev->mutex);
- return ret;
-}
-
-int
-netdev_dpdk_rte_flow_tunnel_action_decap_release(
- struct netdev *netdev,
- struct rte_flow_action *actions,
- uint32_t num_of_actions,
- struct rte_flow_error *error)
-{
- struct netdev_dpdk *dev;
- int ret;
-
- if (!is_dpdk_class(netdev->netdev_class)) {
- return -1;
- }
-
- dev = netdev_dpdk_cast(netdev);
- ovs_mutex_lock(&dev->mutex);
- ret = rte_flow_tunnel_action_decap_release(dev->port_id, actions,
- num_of_actions, error);
- ovs_mutex_unlock(&dev->mutex);
- return ret;
-}
-
-int
-netdev_dpdk_rte_flow_tunnel_item_release(struct netdev *netdev,
- struct rte_flow_item *items,
- uint32_t num_of_items,
- struct rte_flow_error *error)
-{
- struct netdev_dpdk *dev;
- int ret;
-
- if (!is_dpdk_class(netdev->netdev_class)) {
- return -1;
- }
-
- dev = netdev_dpdk_cast(netdev);
- ovs_mutex_lock(&dev->mutex);
- ret = rte_flow_tunnel_item_release(dev->port_id, items, num_of_items,
- error);
- ovs_mutex_unlock(&dev->mutex);
- return ret;
-}
-
-#endif /* ALLOW_EXPERIMENTAL_API */
-
static void
parse_mempool_config(const struct smap *ovs_other_config)
{
diff --git a/lib/netdev-dpdk.h b/lib/netdev-dpdk.h
index 0029372ee..ede8270aa 100644
--- a/lib/netdev-dpdk.h
+++ b/lib/netdev-dpdk.h
@@ -67,91 +67,6 @@ set_error(struct rte_flow_error *error, enum
rte_flow_error_type type)
error->message = NULL;
}
-#ifdef ALLOW_EXPERIMENTAL_API
-
-int netdev_dpdk_rte_flow_tunnel_decap_set(struct netdev *,
- struct rte_flow_tunnel *,
- struct rte_flow_action **,
- uint32_t *num_of_actions,
- struct rte_flow_error *);
-int netdev_dpdk_rte_flow_tunnel_match(struct netdev *,
- struct rte_flow_tunnel *,
- struct rte_flow_item **,
- uint32_t *num_of_items,
- struct rte_flow_error *);
-int netdev_dpdk_rte_flow_get_restore_info(struct netdev *,
- struct dp_packet *,
- struct rte_flow_restore_info *,
- struct rte_flow_error *);
-int netdev_dpdk_rte_flow_tunnel_action_decap_release(struct netdev *,
- struct rte_flow_action *,
- uint32_t num_of_actions,
- struct rte_flow_error *);
-int netdev_dpdk_rte_flow_tunnel_item_release(struct netdev *,
- struct rte_flow_item *,
- uint32_t num_of_items,
- struct rte_flow_error *);
-
-#else
-
-static inline int
-netdev_dpdk_rte_flow_tunnel_decap_set(
- struct netdev *netdev OVS_UNUSED,
- struct rte_flow_tunnel *tunnel OVS_UNUSED,
- struct rte_flow_action **actions OVS_UNUSED,
- uint32_t *num_of_actions OVS_UNUSED,
- struct rte_flow_error *error)
-{
- set_error(error, RTE_FLOW_ERROR_TYPE_ACTION);
- return -1;
-}
-
-static inline int
-netdev_dpdk_rte_flow_tunnel_match(struct netdev *netdev OVS_UNUSED,
- struct rte_flow_tunnel *tunnel OVS_UNUSED,
- struct rte_flow_item **items OVS_UNUSED,
- uint32_t *num_of_items OVS_UNUSED,
- struct rte_flow_error *error)
-{
- set_error(error, RTE_FLOW_ERROR_TYPE_ITEM);
- return -1;
-}
-
-static inline int
-netdev_dpdk_rte_flow_get_restore_info(
- struct netdev *netdev OVS_UNUSED,
- struct dp_packet *p OVS_UNUSED,
- struct rte_flow_restore_info *info OVS_UNUSED,
- struct rte_flow_error *error)
-{
- set_error(error, RTE_FLOW_ERROR_TYPE_ATTR);
- return -1;
-}
-
-static inline int
-netdev_dpdk_rte_flow_tunnel_action_decap_release(
- struct netdev *netdev OVS_UNUSED,
- struct rte_flow_action *actions OVS_UNUSED,
- uint32_t num_of_actions OVS_UNUSED,
- struct rte_flow_error *error)
-{
- set_error(error, RTE_FLOW_ERROR_TYPE_NONE);
- return 0;
-}
-
-static inline int
-netdev_dpdk_rte_flow_tunnel_item_release(
- struct netdev *netdev OVS_UNUSED,
- struct rte_flow_item *items OVS_UNUSED,
- uint32_t num_of_items OVS_UNUSED,
- struct rte_flow_error *error)
-{
- set_error(error, RTE_FLOW_ERROR_TYPE_NONE);
- return 0;
-}
-
-#endif /* ALLOW_EXPERIMENTAL_API */
-
#else
static inline void