ACTION_SET_TAG_DATA,
ACTION_SET_TAG_INDEX,
ACTION_SET_TAG_MASK,
+ ACTION_SET_META,
+ ACTION_SET_META_DATA,
+ ACTION_SET_META_MASK,
};
/** Maximum size for pattern in struct rte_flow_item_raw. */
ACTION_RAW_ENCAP,
ACTION_RAW_DECAP,
ACTION_SET_TAG,
+ ACTION_SET_META,
ZERO,
};
ZERO,
};
+static const enum index action_set_meta[] = {
+ ACTION_SET_META_DATA,
+ ACTION_SET_META_MASK,
+ ACTION_NEXT,
+ ZERO,
+};
+
static int parse_set_raw_encap_decap(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
static int parse_vc_action_raw_decap_index(struct context *,
const struct token *, const char *,
unsigned int, void *, unsigned int);
+static int parse_vc_action_set_meta(struct context *ctx,
+ const struct token *token, const char *str,
+ unsigned int len, void *buf,
+ unsigned int size);
static int parse_destroy(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
.name = "data",
.help = "metadata value",
.next = NEXT(item_meta, NEXT_ENTRY(UNSIGNED), item_param),
- .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_meta,
- data, "\xff\xff\xff\xff")),
+ .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_meta,
+ data, "\xff\xff\xff\xff")),
},
[ITEM_GRE_KEY] = {
.name = "gre_key",
.name = "data",
.help = "tag value to match",
.next = NEXT(item_tag, NEXT_ENTRY(UNSIGNED), item_param),
- .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tag, data)),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, data)),
},
[ITEM_TAG_INDEX] = {
.name = "index",
.name = "data",
.help = "tag value",
.next = NEXT(action_set_tag, NEXT_ENTRY(UNSIGNED)),
- .args = ARGS(ARGS_ENTRY_HTON
+ .args = ARGS(ARGS_ENTRY
(struct rte_flow_action_set_tag, data)),
.call = parse_vc_conf,
},
.name = "mask",
.help = "mask for tag value",
.next = NEXT(action_set_tag, NEXT_ENTRY(UNSIGNED)),
- .args = ARGS(ARGS_ENTRY_HTON
+ .args = ARGS(ARGS_ENTRY
(struct rte_flow_action_set_tag, mask)),
.call = parse_vc_conf,
},
+ [ACTION_SET_META] = {
+ .name = "set_meta",
+ .help = "set metadata",
+ .priv = PRIV_ACTION(SET_META,
+ sizeof(struct rte_flow_action_set_meta)),
+ .next = NEXT(action_set_meta),
+ .call = parse_vc_action_set_meta,
+ },
+ [ACTION_SET_META_DATA] = {
+ .name = "data",
+ .help = "metadata value",
+ .next = NEXT(action_set_meta, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY
+ (struct rte_flow_action_set_meta, data)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_SET_META_MASK] = {
+ .name = "mask",
+ .help = "mask for metadata value",
+ .next = NEXT(action_set_meta, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY
+ (struct rte_flow_action_set_meta, mask)),
+ .call = parse_vc_conf,
+ },
};
/** Remove and return last entry from argument stack. */
return ret;
}
+static int
+parse_vc_action_set_meta(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len, void *buf,
+ unsigned int size)
+{
+ int ret;
+
+ ret = parse_vc(ctx, token, str, len, buf, size);
+ if (ret < 0)
+ return ret;
+ ret = rte_flow_dynf_metadata_register();
+ if (ret < 0)
+ return -1;
+ return len;
+}
+
/** Parse tokens for destroy command. */
static int
parse_destroy(struct context *ctx, const struct token *token,
case RTE_FLOW_ITEM_TYPE_IPV4:
ipv4 = (struct rte_flow_item_ipv4 *)buf;
ipv4->hdr.version_ihl = 0x45;
- ipv4->hdr.next_proto_id = (uint8_t)next_proto;
+ if (next_proto && ipv4->hdr.next_proto_id == 0)
+ ipv4->hdr.next_proto_id = (uint8_t)next_proto;
break;
case RTE_FLOW_ITEM_TYPE_IPV6:
ipv6 = (struct rte_flow_item_ipv6 *)buf;
- ipv6->hdr.proto = (uint8_t)next_proto;
+ if (next_proto && ipv6->hdr.proto == 0)
+ ipv6->hdr.proto = (uint8_t)next_proto;
ipv6_vtc_flow = rte_be_to_cpu_32(ipv6->hdr.vtc_flow);
ipv6_vtc_flow &= 0x0FFFFFFF; /*< reset version bits. */
ipv6_vtc_flow |= 0x60000000; /*< set ipv6 version. */
break;
case RTE_FLOW_ITEM_TYPE_GRE_KEY:
size = sizeof(rte_be32_t);
+ proto = 0x0;
break;
case RTE_FLOW_ITEM_TYPE_MPLS:
size = sizeof(struct rte_flow_item_mpls);
+ proto = 0x0;
break;
case RTE_FLOW_ITEM_TYPE_NVGRE:
size = sizeof(struct rte_flow_item_nvgre);