@@ -2399,7 +2399,6 @@ static int
dp_netdev_flow_offload_put(struct dp_flow_offload_item *offload)
{
struct dp_netdev_pmd_thread *pmd = offload->pmd;
- const struct dpif_class *dpif_class = pmd->dp->class;
struct dp_netdev_flow *flow = offload->flow;
odp_port_t in_port = flow->flow.in_port.odp_port;
const char *dpif_type_str = dpif_normalize_type(pmd->dp->class->type);
@@ -419,6 +419,8 @@ dump_flow_action(struct ds *s, const struct rte_flow_action *actions)
while (items && items->type != RTE_FLOW_ITEM_TYPE_END) {
dump_flow_pattern(s, items++);
}
+ } else if (actions->type == RTE_FLOW_ACTION_TYPE_VXLAN_DECAP) {
+ ds_put_format(s, "vxlan-decap: nop\n");
} else if (actions->type == RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN) {
const struct rte_flow_action_of_push_vlan *vlan_tci = actions->conf;
@@ -627,8 +629,40 @@ free_flow_actions(struct flow_actions *actions)
}
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 0;
+ }
+
+ /* no need to tranmit layer2/layer3/layer4 as
+ * for outer key fpga only support vni */
+ /*
+ ret = parse_tnl_ip_match(patterns, match, IPPROTO_UDP);
+ parse_tnl_udp_match(patterns, match);
+ */
+
+ /* VXLAN */
+ vx_spec = xzalloc(sizeof *vx_spec);
+ vx_mask = xzalloc(sizeof *vx_mask);
+
+ put_unaligned_be32((ovs_be32 *)vx_spec->vni,
+ htonl(ntohll(match->flow.tunnel.tun_id) << 8));
+ put_unaligned_be32((ovs_be32 *)vx_mask->vni,
+ htonl(ntohll(match->wc.masks.tunnel.tun_id) << 8));
+
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_VXLAN, vx_spec, vx_mask);
+ return 0;
+}
+
+static int
parse_flow_match(struct flow_patterns *patterns,
- const struct match *match)
+ const struct match *match,
+ struct netdev *netdev,
+ struct offload_info *info)
{
uint8_t *next_proto_mask = NULL;
uint8_t proto = 0;
@@ -643,6 +677,15 @@ parse_flow_match(struct flow_patterns *patterns,
consumed_masks->recirc_id = 0;
consumed_masks->packet_type = 0;
+ 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;
+ }
+
/* Eth */
if (!eth_addr_is_zero(match->wc.masks.dl_src) ||
!eth_addr_is_zero(match->wc.masks.dl_dst)) {
@@ -1289,6 +1332,10 @@ 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;
@@ -1335,7 +1382,7 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev,
struct rte_flow *flow;
int ret = 0;
- ret = parse_flow_match(&patterns, match);
+ ret = parse_flow_match(&patterns, match, netdev, info);
if (ret) {
goto out;
}
@@ -77,6 +77,7 @@ 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 */
};
int netdev_flow_flush(struct netdev *);
From: Liuchang <liuchang@cmss.chinamobile.com> Code Source From: Self Code Description: add vxlan decap action offloading mechanism Jira: #[Optional] 市场项目编号(名称):[Optional] --- lib/dpif-netdev.c | 1 - lib/netdev-offload-dpdk.c | 51 +++++++++++++++++++++++++++++++++++++++++++++-- lib/netdev-offload.h | 1 + 3 files changed, 50 insertions(+), 3 deletions(-)