@@ -5328,6 +5328,25 @@ out:
}
bool
+netdev_dpdk_is_uplink_port(struct netdev *netdev)
+{
+ struct netdev_dpdk *dev;
+ bool ret = false;
+
+ if (!is_dpdk_class(netdev->netdev_class)) {
+ goto out;
+ }
+
+ dev = netdev_dpdk_cast(netdev);
+ ovs_mutex_lock(&dev->mutex);
+ /*ret = dev->is_uplink_port;*/
+ ret = (dev->type == DPDK_DEV_ETH);
+ ovs_mutex_unlock(&dev->mutex);
+out:
+ return ret;
+}
+
+bool
netdev_dpdk_flow_api_supported(struct netdev *netdev)
{
struct netdev_dpdk *dev;
@@ -5378,8 +5397,10 @@ netdev_dpdk_rte_flow_create(struct netdev *netdev,
struct rte_flow *flow;
struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
+ VLOG_DBG("TIMO DBG: in netdev_dpdk_rte_flow_create");
ovs_mutex_lock(&dev->mutex);
flow = rte_flow_create(dev->port_id, attr, items, actions, error);
+ VLOG_DBG("TIMO DBG: after rte_flow_create");
ovs_mutex_unlock(&dev->mutex);
return flow;
}
@@ -56,6 +56,9 @@ netdev_dpdk_rte_flow_query_count(struct netdev *netdev,
int
netdev_dpdk_get_port_id(struct netdev *netdev);
+bool
+netdev_dpdk_is_uplink_port(struct netdev *netdev);
+
#else
static inline void
@@ -142,6 +142,7 @@ struct flow_actions {
struct rte_flow_action *actions;
int cnt;
int current_max;
+ bool valid_ucast; /* flag to judge multicast && broadcast */
};
static void
@@ -516,6 +517,7 @@ netdev_offload_dpdk_flow_create(struct netdev *netdev,
struct rte_flow *flow;
struct ds s;
+ VLOG_DBG("TIMO DBG: in netdev_offload_dpdk_flow_create %s",netdev->name);
flow = netdev_dpdk_rte_flow_create(netdev, attr, items, actions, error);
/* work around: for dump_flow even if rte_flow create fail */
if (!VLOG_DROP_DBG(&rl)) {
@@ -580,6 +582,11 @@ add_flow_action(struct flow_actions *actions, enum rte_flow_action_type type,
{
int cnt = actions->cnt;
+ if ( (actions->valid_ucast == true) &&
+ (type == RTE_FLOW_ACTION_TYPE_PORT_ID) ) {
+ VLOG_DBG_RL(&rl, "Unsupported multicast output action");
+ return ;
+ }
if (cnt == 0) {
actions->current_max = 8;
actions->actions = xcalloc(actions->current_max,
@@ -593,6 +600,8 @@ add_flow_action(struct flow_actions *actions, enum rte_flow_action_type type,
actions->actions[cnt].type = type;
actions->actions[cnt].conf = conf;
actions->cnt++;
+ actions->valid_ucast = (type == RTE_FLOW_ACTION_TYPE_PORT_ID)?
+ true : actions->valid_ucast;
}
static void
@@ -626,16 +635,17 @@ free_flow_actions(struct flow_actions *actions)
free(actions->actions);
actions->actions = NULL;
actions->cnt = 0;
+ actions->valid_ucast = false;
}
-static void
+static int
parse_vxlan_match(struct flow_patterns *patterns,
const struct match *match)
{
struct rte_flow_item_vxlan *vx_spec, *vx_mask;
if (is_all_zeros(&match->wc.masks.tunnel, sizeof match->wc.masks.tunnel)) {
- return ;
+ return -1;
}
VLOG_DBG("TIMO:in parse_vxlan_match");
@@ -656,32 +666,29 @@ parse_vxlan_match(struct flow_patterns *patterns,
htonl(ntohll(match->wc.masks.tunnel.tun_id) << 8));
add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_VXLAN, vx_spec, vx_mask);
- return ;
+ return 0;
}
static int
parse_flow_match(struct flow_patterns *patterns,
- const struct match *match,
+ struct match *match,
struct netdev *netdev,
struct offload_info *info)
{
uint8_t *next_proto_mask = NULL;
uint8_t proto = 0;
- struct match consumed_match;
struct flow *consumed_masks;
- memcpy(&consumed_match, match, sizeof consumed_match);
- consumed_masks = &(consumed_match.wc.masks);
+ consumed_masks = &match->wc.masks;
/* Not attemp to offload in_port/recirc_id ? */
memset(&consumed_masks->in_port, 0, sizeof consumed_masks->in_port);
consumed_masks->recirc_id = 0;
consumed_masks->packet_type = 0;
- if (!strcmp(netdev_get_type(netdev), "vxlan")) {
- parse_vxlan_match(patterns, match);
+ if (!strcmp(netdev_get_type(netdev), "vxlan") &&
+ !parse_vxlan_match(patterns, match)) {
memset(&consumed_masks->tunnel, 0, sizeof consumed_masks->tunnel);
- info->vxlan_decap = true;
} else if (netdev_vport_is_vport_class(netdev->netdev_class)) {
VLOG_DBG("in port (%s) not supported", netdev->name);
return -1;
@@ -946,14 +953,16 @@ netdev_offload_dpdk_mark_rss(struct flow_patterns *patterns,
.ingress = 1,
.egress = 0
};
- struct rte_flow_error error;
struct rte_flow *flow;
+ /* work around : not do mark rss action
+ struct rte_flow_error error;
add_flow_mark_rss_actions(&actions, flow_mark, netdev);
flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, patterns->items,
actions.actions, &error);
+ */
free_flow_actions(&actions);
return flow;
}
@@ -973,6 +982,7 @@ add_port_id_action(struct flow_actions *actions,
struct rte_flow_action_port_id *port_id;
int outdev_id;
+ VLOG_DBG("TIMO DBG: in add_port_id_action");
outdev_id = netdev_dpdk_get_port_id(outdev);
if (outdev_id < 0) {
return -1;
@@ -993,6 +1003,7 @@ add_output_action(struct netdev *netdev,
odp_port_t port;
int ret = 0;
+ VLOG_DBG("TIMO DBG: in add_output_action");
port = nl_attr_get_odp_port(nla);
outdev = netdev_ports_get(port, info->dpif_type_str);
if (outdev == NULL) {
@@ -1221,6 +1232,13 @@ err:
return -1;
}
+static void
+add_vxlan_decap_action(struct flow_actions *actions)
+{
+ VLOG_DBG("TIMO DBG: in add_vxlan_decap_action");
+ add_flow_action(actions, RTE_FLOW_ACTION_TYPE_VXLAN_DECAP, NULL);
+}
+
static int
parse_clone_actions(struct netdev *netdev,
struct flow_actions *actions,
@@ -1248,13 +1266,6 @@ parse_clone_actions(struct netdev *netdev,
if (add_output_action(netdev, actions, ca, info)) {
return -1;
}
- /*
- } else if (info->valid_ucast) {
- VLOG_DBG_RL(&rl, "Unsupported multicast output action");
- return -1;
- info->valid_ucast = true;
- }
- */
} else if (clone_type == OVS_ACTION_ATTR_PUSH_VLAN) {
const struct ovs_action_push_vlan *vlan = nl_attr_get(ca);
struct rte_flow_action_of_push_vlan *vlan_tci;
@@ -1288,6 +1299,9 @@ parse_flow_actions(struct netdev *netdev,
uint8_t i = 0;
+ if (nl_actions_len != 0 && !strcmp(netdev_get_type(netdev), "vxlan")) {
+ add_vxlan_decap_action(actions);
+ }
add_count_action(actions);
NL_ATTR_FOR_EACH_UNSAFE (nla, left, nl_actions, nl_actions_len) {
@@ -1295,12 +1309,6 @@ parse_flow_actions(struct netdev *netdev,
if (nl_attr_type(nla) == OVS_ACTION_ATTR_OUTPUT) {
if (add_output_action(netdev, actions, nla, info)) {
return -1;
- /*
- } else if (info->valid_ucast) {
- VLOG_DBG_RL(&rl, "Unsupported multicast output action");
- return -1;
- info->valid_ucast = true;
- */
}
} else if (nl_attr_type(nla) == OVS_ACTION_ATTR_DROP) {
add_flow_action(actions, RTE_FLOW_ACTION_TYPE_DROP, NULL);
@@ -1338,10 +1346,6 @@ parse_flow_actions(struct netdev *netdev,
}
}
- if (info->vxlan_decap) {
- add_flow_action(actions, RTE_FLOW_ACTION_TYPE_VXLAN_DECAP, NULL);
- info->vxlan_decap = false;
- }
if (nl_actions_len == 0) {
VLOG_DBG_RL(&rl, "No actions provided");
return -1;
@@ -1359,17 +1363,38 @@ netdev_offload_dpdk_actions(struct netdev *netdev,
struct offload_info *info)
{
const struct rte_flow_attr flow_attr = { .ingress = 1, .transfer = 1 };
- struct flow_actions actions = { .actions = NULL, .cnt = 0 };
+ struct flow_actions actions = { .actions = NULL, .cnt = 0,
+ .valid_ucast = false };
struct rte_flow *flow = NULL;
struct rte_flow_error error;
- int ret;
+ int ret,i;
ret = parse_flow_actions(netdev, &actions, nl_actions, actions_len, info);
if (ret) {
+ VLOG_DBG("TIMO DBG: after parse_flow_actions, ret is -1");
goto out;
}
- flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, patterns->items,
- actions.actions, &error);
+ if (netdev_vport_is_vport_class(netdev->netdev_class)) {
+ struct netdev_flow_dump **netdev_dumps;
+ int num_ports = 0;
+
+ netdev_dumps = netdev_ports_flow_dump_create(netdev->dpif_type,
+ &num_ports);
+ for (i = 0; i < num_ports; i++) {
+ if (!netdev_dpdk_is_uplink_port(netdev_dumps[i]->netdev)) {
+ continue;
+ }
+ VLOG_DBG("TIMO DBG: in netdev_offload_dpdk_flow_create, netdev dpdk");
+ flow = netdev_offload_dpdk_flow_create(netdev_dumps[i]->netdev,
+ &flow_attr, patterns->items,
+ actions.actions, &error);
+ break;
+ }
+
+ } else {
+ flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, patterns->items,
+ actions.actions, &error);
+ }
out:
free_flow_actions(&actions);
return flow;
@@ -1377,7 +1402,7 @@ out:
static int
netdev_offload_dpdk_add_flow(struct netdev *netdev,
- const struct match *match,
+ struct match *match,
struct nlattr *nl_actions,
size_t actions_len,
const ovs_u128 *ufid,
@@ -76,8 +76,6 @@ struct offload_info {
bool tc_modify_flow_deleted; /* Indicate the tc modify flow put success
* to delete the original flow. */
- bool valid_ucast; /* flag to judge multicast && broadcast */
- bool vxlan_decap; /* flag to turn on vxlan decap */
const char *dpif_type_str; /* dpif type string. */
};
From: Rongyin <rongyin@cmss.chinamobile.com> Code Source From: Self Code Description: When vxlan decap vport should be changed to uplink port to call rte_flow_create Jira: #[Optional] 市场项目编号(名称):[Optional] --- lib/netdev-dpdk.c | 21 +++++++++++ lib/netdev-dpdk.h | 3 ++ lib/netdev-offload-dpdk.c | 91 ++++++++++++++++++++++++++++++----------------- lib/netdev-offload.h | 2 -- 4 files changed, 82 insertions(+), 35 deletions(-)