net/softnic: support flow API VXLAN encap action
Added support for ethdev flow API VXLAN encap action. Signed-off-by: Reshma Pattan <reshma.pattan@intel.com> Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
This commit is contained in:
parent
0dac5d7ea0
commit
636e5af038
@ -1634,6 +1634,198 @@ flow_rule_action_get(struct pmd_internals *softnic,
|
||||
break;
|
||||
} /* RTE_FLOW_ACTION_TYPE_METER */
|
||||
|
||||
case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:
|
||||
{
|
||||
const struct rte_flow_action_vxlan_encap *conf =
|
||||
action->conf;
|
||||
const struct rte_flow_item *item;
|
||||
union flow_item spec, mask;
|
||||
int disabled = 0, status;
|
||||
size_t size;
|
||||
|
||||
if (conf == NULL)
|
||||
return rte_flow_error_set(error,
|
||||
EINVAL,
|
||||
RTE_FLOW_ERROR_TYPE_ACTION,
|
||||
action,
|
||||
"VXLAN ENCAP: Null configuration");
|
||||
|
||||
item = conf->definition;
|
||||
if (item == NULL)
|
||||
return rte_flow_error_set(error,
|
||||
EINVAL,
|
||||
RTE_FLOW_ERROR_TYPE_ACTION,
|
||||
action,
|
||||
"VXLAN ENCAP: Null configuration definition");
|
||||
|
||||
if (!(params->action_mask &
|
||||
(1LLU << RTE_TABLE_ACTION_ENCAP)))
|
||||
return rte_flow_error_set(error,
|
||||
EINVAL,
|
||||
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
|
||||
NULL,
|
||||
"VXLAN ENCAP: Encap action not enabled for this table");
|
||||
|
||||
/* Check for Ether. */
|
||||
flow_item_skip_void(&item);
|
||||
status = flow_item_proto_preprocess(item, &spec, &mask,
|
||||
&size, &disabled, error);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (item->type != RTE_FLOW_ITEM_TYPE_ETH) {
|
||||
return rte_flow_error_set(error,
|
||||
EINVAL,
|
||||
RTE_FLOW_ERROR_TYPE_ITEM,
|
||||
item,
|
||||
"VXLAN ENCAP: first encap item should be ether");
|
||||
}
|
||||
ether_addr_copy(&spec.eth.dst,
|
||||
&rule_action->encap.vxlan.ether.da);
|
||||
ether_addr_copy(&spec.eth.src,
|
||||
&rule_action->encap.vxlan.ether.sa);
|
||||
|
||||
item++;
|
||||
|
||||
/* Check for VLAN. */
|
||||
flow_item_skip_void(&item);
|
||||
status = flow_item_proto_preprocess(item, &spec, &mask,
|
||||
&size, &disabled, error);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) {
|
||||
if (!params->encap.vxlan.vlan)
|
||||
return rte_flow_error_set(error,
|
||||
ENOTSUP,
|
||||
RTE_FLOW_ERROR_TYPE_ITEM,
|
||||
item,
|
||||
"VXLAN ENCAP: vlan encap not supported by table");
|
||||
|
||||
uint16_t tci = rte_ntohs(spec.vlan.tci);
|
||||
rule_action->encap.vxlan.vlan.pcp =
|
||||
tci >> 13;
|
||||
rule_action->encap.vxlan.vlan.dei =
|
||||
(tci >> 12) & 0x1;
|
||||
rule_action->encap.vxlan.vlan.vid =
|
||||
tci & 0xfff;
|
||||
|
||||
item++;
|
||||
|
||||
flow_item_skip_void(&item);
|
||||
status = flow_item_proto_preprocess(item, &spec,
|
||||
&mask, &size, &disabled, error);
|
||||
if (status)
|
||||
return status;
|
||||
} else {
|
||||
if (params->encap.vxlan.vlan)
|
||||
return rte_flow_error_set(error,
|
||||
ENOTSUP,
|
||||
RTE_FLOW_ERROR_TYPE_ITEM,
|
||||
item,
|
||||
"VXLAN ENCAP: expecting vlan encap item");
|
||||
}
|
||||
|
||||
/* Check for IPV4/IPV6. */
|
||||
switch (item->type) {
|
||||
case RTE_FLOW_ITEM_TYPE_IPV4:
|
||||
{
|
||||
rule_action->encap.vxlan.ipv4.sa =
|
||||
rte_ntohl(spec.ipv4.hdr.src_addr);
|
||||
rule_action->encap.vxlan.ipv4.da =
|
||||
rte_ntohl(spec.ipv4.hdr.dst_addr);
|
||||
rule_action->encap.vxlan.ipv4.dscp =
|
||||
spec.ipv4.hdr.type_of_service >> 2;
|
||||
rule_action->encap.vxlan.ipv4.ttl =
|
||||
spec.ipv4.hdr.time_to_live;
|
||||
break;
|
||||
}
|
||||
case RTE_FLOW_ITEM_TYPE_IPV6:
|
||||
{
|
||||
uint32_t vtc_flow;
|
||||
|
||||
memcpy(&rule_action->encap.vxlan.ipv6.sa,
|
||||
&spec.ipv6.hdr.src_addr,
|
||||
sizeof(spec.ipv6.hdr.src_addr));
|
||||
memcpy(&rule_action->encap.vxlan.ipv6.da,
|
||||
&spec.ipv6.hdr.dst_addr,
|
||||
sizeof(spec.ipv6.hdr.dst_addr));
|
||||
vtc_flow = rte_ntohl(spec.ipv6.hdr.vtc_flow);
|
||||
rule_action->encap.vxlan.ipv6.flow_label =
|
||||
vtc_flow & 0xfffff;
|
||||
rule_action->encap.vxlan.ipv6.dscp =
|
||||
(vtc_flow >> 22) & 0x3f;
|
||||
rule_action->encap.vxlan.ipv6.hop_limit =
|
||||
spec.ipv6.hdr.hop_limits;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return rte_flow_error_set(error,
|
||||
EINVAL,
|
||||
RTE_FLOW_ERROR_TYPE_ITEM,
|
||||
item,
|
||||
"VXLAN ENCAP: encap item after ether should be ipv4/ipv6");
|
||||
}
|
||||
|
||||
item++;
|
||||
|
||||
/* Check for UDP. */
|
||||
flow_item_skip_void(&item);
|
||||
status = flow_item_proto_preprocess(item, &spec, &mask,
|
||||
&size, &disabled, error);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (item->type != RTE_FLOW_ITEM_TYPE_UDP) {
|
||||
return rte_flow_error_set(error,
|
||||
EINVAL,
|
||||
RTE_FLOW_ERROR_TYPE_ITEM,
|
||||
item,
|
||||
"VXLAN ENCAP: encap item after ipv4/ipv6 should be udp");
|
||||
}
|
||||
rule_action->encap.vxlan.udp.sp =
|
||||
rte_ntohs(spec.udp.hdr.src_port);
|
||||
rule_action->encap.vxlan.udp.dp =
|
||||
rte_ntohs(spec.udp.hdr.dst_port);
|
||||
|
||||
item++;
|
||||
|
||||
/* Check for VXLAN. */
|
||||
flow_item_skip_void(&item);
|
||||
status = flow_item_proto_preprocess(item, &spec, &mask,
|
||||
&size, &disabled, error);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (item->type != RTE_FLOW_ITEM_TYPE_VXLAN) {
|
||||
return rte_flow_error_set(error,
|
||||
EINVAL,
|
||||
RTE_FLOW_ERROR_TYPE_ITEM,
|
||||
item,
|
||||
"VXLAN ENCAP: encap item after udp should be vxlan");
|
||||
}
|
||||
rule_action->encap.vxlan.vxlan.vni =
|
||||
(spec.vxlan.vni[0] << 16U |
|
||||
spec.vxlan.vni[1] << 8U
|
||||
| spec.vxlan.vni[2]);
|
||||
|
||||
item++;
|
||||
|
||||
/* Check for END. */
|
||||
flow_item_skip_void(&item);
|
||||
|
||||
if (item->type != RTE_FLOW_ITEM_TYPE_END)
|
||||
return rte_flow_error_set(error,
|
||||
EINVAL,
|
||||
RTE_FLOW_ERROR_TYPE_ITEM,
|
||||
item,
|
||||
"VXLAN ENCAP: expecting END item");
|
||||
|
||||
rule_action->encap.type = RTE_TABLE_ACTION_ENCAP_VXLAN;
|
||||
rule_action->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
|
||||
break;
|
||||
} /* RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP */
|
||||
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user