@@ -262,37 +262,13 @@ struct action_rss_data {
uint16_t queue[ACTION_RSS_QUEUE_NUM];
};
-/** Maximum number of items in struct rte_flow_action_vxlan_encap. */
-#define ACTION_VXLAN_ENCAP_ITEMS_NUM 6
-
-/** Storage for struct rte_flow_action_vxlan_encap including external data. */
-struct action_vxlan_encap_data {
- struct rte_flow_action_vxlan_encap conf;
- struct rte_flow_item items[ACTION_VXLAN_ENCAP_ITEMS_NUM];
- struct rte_flow_item_eth item_eth;
- struct rte_flow_item_vlan item_vlan;
- union {
- struct rte_flow_item_ipv4 item_ipv4;
- struct rte_flow_item_ipv6 item_ipv6;
- };
- struct rte_flow_item_udp item_udp;
- struct rte_flow_item_vxlan item_vxlan;
-};
+/** Maximum buffer size for the encap data. */
+#define ACTION_TUNNEL_ENCAP_MAX_BUFFER_SIZE 64
-/** Maximum number of items in struct rte_flow_action_nvgre_encap. */
-#define ACTION_NVGRE_ENCAP_ITEMS_NUM 5
-
-/** Storage for struct rte_flow_action_nvgre_encap including external data. */
-struct action_nvgre_encap_data {
- struct rte_flow_action_nvgre_encap conf;
- struct rte_flow_item items[ACTION_NVGRE_ENCAP_ITEMS_NUM];
- struct rte_flow_item_eth item_eth;
- struct rte_flow_item_vlan item_vlan;
- union {
- struct rte_flow_item_ipv4 item_ipv4;
- struct rte_flow_item_ipv6 item_ipv6;
- };
- struct rte_flow_item_nvgre item_nvgre;
+/** Storage for struct rte_flow_action_tunnel_encap including external data. */
+struct action_tunnel_encap_data {
+ struct rte_flow_action_tunnel_encap conf;
+ uint8_t buf[ACTION_TUNNEL_ENCAP_MAX_BUFFER_SIZE];
};
/** Maximum number of subsequent tokens and arguments on the stack. */
@@ -2438,8 +2414,8 @@ static int comp_vc_action_rss_queue(struct context *, const struct token *,
.name = "vxlan_encap",
.help = "VXLAN encapsulation, uses configuration set by \"set"
" vxlan\"",
- .priv = PRIV_ACTION(VXLAN_ENCAP,
- sizeof(struct action_vxlan_encap_data)),
+ .priv = PRIV_ACTION(TUNNEL_ENCAP,
+ sizeof(struct action_tunnel_encap_data)),
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
.call = parse_vc_action_vxlan_encap,
},
@@ -2448,7 +2424,7 @@ static int comp_vc_action_rss_queue(struct context *, const struct token *,
.help = "Performs a decapsulation action by stripping all"
" headers of the VXLAN tunnel network overlay from the"
" matched flow.",
- .priv = PRIV_ACTION(VXLAN_DECAP, 0),
+ .priv = PRIV_ACTION(TUNNEL_DECAP, 0),
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
.call = parse_vc,
},
@@ -2456,8 +2432,8 @@ static int comp_vc_action_rss_queue(struct context *, const struct token *,
.name = "nvgre_encap",
.help = "NVGRE encapsulation, uses configuration set by \"set"
" nvgre\"",
- .priv = PRIV_ACTION(NVGRE_ENCAP,
- sizeof(struct action_nvgre_encap_data)),
+ .priv = PRIV_ACTION(TUNNEL_ENCAP,
+ sizeof(struct action_tunnel_encap_data)),
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
.call = parse_vc_action_nvgre_encap,
},
@@ -2466,7 +2442,7 @@ static int comp_vc_action_rss_queue(struct context *, const struct token *,
.help = "Performs a decapsulation action by stripping all"
" headers of the NVGRE tunnel network overlay from the"
" matched flow.",
- .priv = PRIV_ACTION(NVGRE_DECAP, 0),
+ .priv = PRIV_ACTION(TUNNEL_DECAP, 0),
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
.call = parse_vc,
},
@@ -3034,6 +3010,9 @@ static int comp_vc_action_rss_queue(struct context *, const struct token *,
return len;
}
+/** IP next protocol UDP. */
+#define IP_PROTO_UDP 0x11
+
/** Parse VXLAN encap action. */
static int
parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token,
@@ -3042,7 +3021,32 @@ static int comp_vc_action_rss_queue(struct context *, const struct token *,
{
struct buffer *out = buf;
struct rte_flow_action *action;
- struct action_vxlan_encap_data *action_vxlan_encap_data;
+ struct action_tunnel_encap_data *action_vxlan_encap_data;
+ struct rte_flow_item_eth eth = { .type = 0, };
+ struct rte_flow_item_vlan vlan = {
+ .tci = vxlan_encap_conf.vlan_tci,
+ .inner_type = 0,
+ };
+ struct rte_flow_item_ipv4 ipv4 = {
+ .hdr = {
+ .src_addr = vxlan_encap_conf.ipv4_src,
+ .dst_addr = vxlan_encap_conf.ipv4_dst,
+ .next_proto_id = IP_PROTO_UDP,
+ },
+ };
+ struct rte_flow_item_ipv6 ipv6 = {
+ .hdr = {
+ .proto = IP_PROTO_UDP,
+ },
+ };
+ struct rte_flow_item_udp udp = {
+ .hdr = {
+ .src_port = vxlan_encap_conf.udp_src,
+ .dst_port = vxlan_encap_conf.udp_dst,
+ },
+ };
+ struct rte_flow_item_vxlan vxlan = { .flags = 0, };
+ uint8_t *header;
int ret;
ret = parse_vc(ctx, token, str, len, buf, size);
@@ -3057,79 +3061,55 @@ static int comp_vc_action_rss_queue(struct context *, const struct token *,
/* Point to selected object. */
ctx->object = out->args.vc.data;
ctx->objmask = NULL;
- /* Set up default configuration. */
+ /* Copy the headers to the buffer. */
action_vxlan_encap_data = ctx->object;
- *action_vxlan_encap_data = (struct action_vxlan_encap_data){
- .conf = (struct rte_flow_action_vxlan_encap){
- .definition = action_vxlan_encap_data->items,
- },
- .items = {
- {
- .type = RTE_FLOW_ITEM_TYPE_ETH,
- .spec = &action_vxlan_encap_data->item_eth,
- .mask = &rte_flow_item_eth_mask,
- },
- {
- .type = RTE_FLOW_ITEM_TYPE_VLAN,
- .spec = &action_vxlan_encap_data->item_vlan,
- .mask = &rte_flow_item_vlan_mask,
- },
- {
- .type = RTE_FLOW_ITEM_TYPE_IPV4,
- .spec = &action_vxlan_encap_data->item_ipv4,
- .mask = &rte_flow_item_ipv4_mask,
- },
- {
- .type = RTE_FLOW_ITEM_TYPE_UDP,
- .spec = &action_vxlan_encap_data->item_udp,
- .mask = &rte_flow_item_udp_mask,
- },
- {
- .type = RTE_FLOW_ITEM_TYPE_VXLAN,
- .spec = &action_vxlan_encap_data->item_vxlan,
- .mask = &rte_flow_item_vxlan_mask,
- },
- {
- .type = RTE_FLOW_ITEM_TYPE_END,
- },
- },
- .item_eth.type = 0,
- .item_vlan = {
- .tci = vxlan_encap_conf.vlan_tci,
- .inner_type = 0,
- },
- .item_ipv4.hdr = {
- .src_addr = vxlan_encap_conf.ipv4_src,
- .dst_addr = vxlan_encap_conf.ipv4_dst,
- },
- .item_udp.hdr = {
- .src_port = vxlan_encap_conf.udp_src,
- .dst_port = vxlan_encap_conf.udp_dst,
+ *action_vxlan_encap_data = (struct action_tunnel_encap_data) {
+ .conf = (struct rte_flow_action_tunnel_encap){
+ .buf = action_vxlan_encap_data->buf,
},
- .item_vxlan.flags = 0,
+ .buf = {},
};
- memcpy(action_vxlan_encap_data->item_eth.dst.addr_bytes,
+ header = action_vxlan_encap_data->buf;
+ if (vxlan_encap_conf.select_vlan)
+ eth.type = rte_cpu_to_be_16(ETHER_TYPE_VLAN);
+ else if (vxlan_encap_conf.select_ipv4)
+ eth.type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+ else
+ eth.type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+ memcpy(eth.dst.addr_bytes,
vxlan_encap_conf.eth_dst, ETHER_ADDR_LEN);
- memcpy(action_vxlan_encap_data->item_eth.src.addr_bytes,
+ memcpy(eth.src.addr_bytes,
vxlan_encap_conf.eth_src, ETHER_ADDR_LEN);
- if (!vxlan_encap_conf.select_ipv4) {
- memcpy(&action_vxlan_encap_data->item_ipv6.hdr.src_addr,
+ memcpy(header, ð, sizeof(eth));
+ header += sizeof(eth);
+ if (vxlan_encap_conf.select_vlan) {
+ if (vxlan_encap_conf.select_ipv4)
+ vlan.inner_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+ else
+ vlan.inner_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+ memcpy(header, &vlan, sizeof(vlan));
+ header += sizeof(vlan);
+ }
+ if (vxlan_encap_conf.select_ipv4) {
+ memcpy(header, &ipv4, sizeof(ipv4));
+ header += sizeof(ipv4);
+ } else {
+ memcpy(&ipv6.hdr.src_addr,
&vxlan_encap_conf.ipv6_src,
sizeof(vxlan_encap_conf.ipv6_src));
- memcpy(&action_vxlan_encap_data->item_ipv6.hdr.dst_addr,
+ memcpy(&ipv6.hdr.dst_addr,
&vxlan_encap_conf.ipv6_dst,
sizeof(vxlan_encap_conf.ipv6_dst));
- action_vxlan_encap_data->items[2] = (struct rte_flow_item){
- .type = RTE_FLOW_ITEM_TYPE_IPV6,
- .spec = &action_vxlan_encap_data->item_ipv6,
- .mask = &rte_flow_item_ipv6_mask,
- };
+ memcpy(header, &ipv6, sizeof(ipv6));
+ header += sizeof(ipv6);
}
- if (!vxlan_encap_conf.select_vlan)
- action_vxlan_encap_data->items[1].type =
- RTE_FLOW_ITEM_TYPE_VOID;
- memcpy(action_vxlan_encap_data->item_vxlan.vni, vxlan_encap_conf.vni,
- RTE_DIM(vxlan_encap_conf.vni));
+ memcpy(header, &udp, sizeof(udp));
+ header += sizeof(udp);
+ memcpy(vxlan.vni, vxlan_encap_conf.vni, RTE_DIM(vxlan_encap_conf.vni));
+ memcpy(header, &vxlan, sizeof(vxlan));
+ header += sizeof(vxlan);
+ action_vxlan_encap_data->conf.size = header -
+ action_vxlan_encap_data->buf;
action->conf = &action_vxlan_encap_data->conf;
return ret;
}
@@ -3142,7 +3122,26 @@ static int comp_vc_action_rss_queue(struct context *, const struct token *,
{
struct buffer *out = buf;
struct rte_flow_action *action;
- struct action_nvgre_encap_data *action_nvgre_encap_data;
+ struct action_tunnel_encap_data *action_nvgre_encap_data;
+ struct rte_flow_item_eth eth = { .type = 0, };
+ struct rte_flow_item_vlan vlan = {
+ .tci = nvgre_encap_conf.vlan_tci,
+ .inner_type = 0,
+ };
+ struct rte_flow_item_ipv4 ipv4 = {
+ .hdr = {
+ .src_addr = nvgre_encap_conf.ipv4_src,
+ .dst_addr = nvgre_encap_conf.ipv4_dst,
+ .next_proto_id = IP_PROTO_UDP,
+ },
+ };
+ struct rte_flow_item_ipv6 ipv6 = {
+ .hdr = {
+ .proto = IP_PROTO_UDP,
+ },
+ };
+ struct rte_flow_item_nvgre nvgre = { .flow_id = 0, };
+ uint8_t *header;
int ret;
ret = parse_vc(ctx, token, str, len, buf, size);
@@ -3157,70 +3156,53 @@ static int comp_vc_action_rss_queue(struct context *, const struct token *,
/* Point to selected object. */
ctx->object = out->args.vc.data;
ctx->objmask = NULL;
- /* Set up default configuration. */
+ /* Copy the headers to the buffer. */
action_nvgre_encap_data = ctx->object;
- *action_nvgre_encap_data = (struct action_nvgre_encap_data){
- .conf = (struct rte_flow_action_nvgre_encap){
- .definition = action_nvgre_encap_data->items,
- },
- .items = {
- {
- .type = RTE_FLOW_ITEM_TYPE_ETH,
- .spec = &action_nvgre_encap_data->item_eth,
- .mask = &rte_flow_item_eth_mask,
- },
- {
- .type = RTE_FLOW_ITEM_TYPE_VLAN,
- .spec = &action_nvgre_encap_data->item_vlan,
- .mask = &rte_flow_item_vlan_mask,
- },
- {
- .type = RTE_FLOW_ITEM_TYPE_IPV4,
- .spec = &action_nvgre_encap_data->item_ipv4,
- .mask = &rte_flow_item_ipv4_mask,
- },
- {
- .type = RTE_FLOW_ITEM_TYPE_NVGRE,
- .spec = &action_nvgre_encap_data->item_nvgre,
- .mask = &rte_flow_item_nvgre_mask,
- },
- {
- .type = RTE_FLOW_ITEM_TYPE_END,
- },
- },
- .item_eth.type = 0,
- .item_vlan = {
- .tci = nvgre_encap_conf.vlan_tci,
- .inner_type = 0,
- },
- .item_ipv4.hdr = {
- .src_addr = nvgre_encap_conf.ipv4_src,
- .dst_addr = nvgre_encap_conf.ipv4_dst,
+ *action_nvgre_encap_data = (struct action_tunnel_encap_data) {
+ .conf = (struct rte_flow_action_tunnel_encap){
+ .buf = action_nvgre_encap_data->buf,
},
- .item_nvgre.flow_id = 0,
+ .buf = {},
};
- memcpy(action_nvgre_encap_data->item_eth.dst.addr_bytes,
+ header = action_nvgre_encap_data->buf;
+ if (nvgre_encap_conf.select_vlan)
+ eth.type = rte_cpu_to_be_16(ETHER_TYPE_VLAN);
+ else if (nvgre_encap_conf.select_ipv4)
+ eth.type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+ else
+ eth.type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+ memcpy(eth.dst.addr_bytes,
nvgre_encap_conf.eth_dst, ETHER_ADDR_LEN);
- memcpy(action_nvgre_encap_data->item_eth.src.addr_bytes,
+ memcpy(eth.src.addr_bytes,
nvgre_encap_conf.eth_src, ETHER_ADDR_LEN);
- if (!nvgre_encap_conf.select_ipv4) {
- memcpy(&action_nvgre_encap_data->item_ipv6.hdr.src_addr,
+ memcpy(header, ð, sizeof(eth));
+ header += sizeof(eth);
+ if (nvgre_encap_conf.select_vlan) {
+ if (nvgre_encap_conf.select_ipv4)
+ vlan.inner_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+ else
+ vlan.inner_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+ memcpy(header, &vlan, sizeof(vlan));
+ header += sizeof(vlan);
+ }
+ if (nvgre_encap_conf.select_ipv4) {
+ memcpy(header, &ipv4, sizeof(ipv4));
+ header += sizeof(ipv4);
+ } else {
+ memcpy(&ipv6.hdr.src_addr,
&nvgre_encap_conf.ipv6_src,
sizeof(nvgre_encap_conf.ipv6_src));
- memcpy(&action_nvgre_encap_data->item_ipv6.hdr.dst_addr,
+ memcpy(&ipv6.hdr.dst_addr,
&nvgre_encap_conf.ipv6_dst,
sizeof(nvgre_encap_conf.ipv6_dst));
- action_nvgre_encap_data->items[2] = (struct rte_flow_item){
- .type = RTE_FLOW_ITEM_TYPE_IPV6,
- .spec = &action_nvgre_encap_data->item_ipv6,
- .mask = &rte_flow_item_ipv6_mask,
- };
+ memcpy(header, &ipv6, sizeof(ipv6));
+ header += sizeof(ipv6);
}
- if (!nvgre_encap_conf.select_vlan)
- action_nvgre_encap_data->items[1].type =
- RTE_FLOW_ITEM_TYPE_VOID;
- memcpy(action_nvgre_encap_data->item_nvgre.tni, nvgre_encap_conf.tni,
- RTE_DIM(nvgre_encap_conf.tni));
+ memcpy(nvgre.tni, nvgre_encap_conf.tni, RTE_DIM(nvgre_encap_conf.tni));
+ memcpy(header, &nvgre, sizeof(nvgre));
+ header += sizeof(nvgre);
+ action_nvgre_encap_data->conf.size = header -
+ action_nvgre_encap_data->buf;
action->conf = &action_nvgre_encap_data->conf;
return ret;
}
@@ -1009,8 +1009,6 @@ void print_valid_ports(void)
printf("Set MTU failed. diag=%d\n", diag);
}
-/* Generic flow management functions. */
-
/** Generate a port_flow entry from attributes/pattern/actions. */
static struct port_flow *
port_flow_new(const struct rte_flow_attr *attr,