+ [ACTIONS_TEMPLATE_INGRESS] = {
+ .name = "ingress",
+ .help = "attribute actions to ingress",
+ .next = NEXT(next_at_attr),
+ .call = parse_template,
+ },
+ [ACTIONS_TEMPLATE_EGRESS] = {
+ .name = "egress",
+ .help = "attribute actions to egress",
+ .next = NEXT(next_at_attr),
+ .call = parse_template,
+ },
+ [ACTIONS_TEMPLATE_TRANSFER] = {
+ .name = "transfer",
+ .help = "attribute actions to transfer",
+ .next = NEXT(next_at_attr),
+ .call = parse_template,
+ },
+ [ACTIONS_TEMPLATE_SPEC] = {
+ .name = "template",
+ .help = "specify action to create actions template",
+ .next = NEXT(next_action),
+ .call = parse_template,
+ },
+ [ACTIONS_TEMPLATE_MASK] = {
+ .name = "mask",
+ .help = "specify action mask to create actions template",
+ .next = NEXT(next_action),
+ .call = parse_template,
+ },
+ /* Top-level command. */
+ [TABLE] = {
+ .name = "template_table",
+ .type = "{command} {port_id} [{arg} [...]]",
+ .help = "manage template tables",
+ .next = NEXT(next_table_subcmd, NEXT_ENTRY(COMMON_PORT_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, port)),
+ .call = parse_table,
+ },
+ /* Sub-level commands. */
+ [TABLE_CREATE] = {
+ .name = "create",
+ .help = "create template table",
+ .next = NEXT(next_table_attr),
+ .call = parse_table,
+ },
+ [TABLE_DESTROY] = {
+ .name = "destroy",
+ .help = "destroy template table",
+ .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, port)),
+ .call = parse_table_destroy,
+ },
+ /* Table arguments. */
+ [TABLE_CREATE_ID] = {
+ .name = "table_id",
+ .help = "specify table id to create",
+ .next = NEXT(next_table_attr,
+ NEXT_ENTRY(COMMON_TABLE_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)),
+ },
+ [TABLE_DESTROY_ID] = {
+ .name = "table",
+ .help = "specify table id to destroy",
+ .next = NEXT(next_table_destroy_attr,
+ NEXT_ENTRY(COMMON_TABLE_ID)),
+ .args = ARGS(ARGS_ENTRY_PTR(struct buffer,
+ args.table_destroy.table_id)),
+ .call = parse_table_destroy,
+ },
+ [TABLE_GROUP] = {
+ .name = "group",
+ .help = "specify a group",
+ .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_GROUP_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer,
+ args.table.attr.flow_attr.group)),
+ },
+ [TABLE_PRIORITY] = {
+ .name = "priority",
+ .help = "specify a priority level",
+ .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)),
+ .args = ARGS(ARGS_ENTRY(struct buffer,
+ args.table.attr.flow_attr.priority)),
+ },
+ [TABLE_EGRESS] = {
+ .name = "egress",
+ .help = "affect rule to egress",
+ .next = NEXT(next_table_attr),
+ .call = parse_table,
+ },
+ [TABLE_INGRESS] = {
+ .name = "ingress",
+ .help = "affect rule to ingress",
+ .next = NEXT(next_table_attr),
+ .call = parse_table,
+ },
+ [TABLE_TRANSFER] = {
+ .name = "transfer",
+ .help = "affect rule to transfer",
+ .next = NEXT(next_table_attr),
+ .call = parse_table,
+ },
+ [TABLE_RULES_NUMBER] = {
+ .name = "rules_number",
+ .help = "number of rules in table",
+ .next = NEXT(next_table_attr,
+ NEXT_ENTRY(COMMON_UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY(struct buffer,
+ args.table.attr.nb_flows)),
+ },
+ [TABLE_PATTERN_TEMPLATE] = {
+ .name = "pattern_template",
+ .help = "specify pattern template id",
+ .next = NEXT(next_table_attr,
+ NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)),
+ .args = ARGS(ARGS_ENTRY_PTR(struct buffer,
+ args.table.pat_templ_id)),
+ .call = parse_table,
+ },
+ [TABLE_ACTIONS_TEMPLATE] = {
+ .name = "actions_template",
+ .help = "specify actions template id",
+ .next = NEXT(next_table_attr,
+ NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)),
+ .args = ARGS(ARGS_ENTRY_PTR(struct buffer,
+ args.table.act_templ_id)),
+ .call = parse_table,
+ },
+ /* Top-level command. */
+ [QUEUE] = {
+ .name = "queue",
+ .help = "queue a flow rule operation",
+ .next = NEXT(next_queue_subcmd, NEXT_ENTRY(COMMON_PORT_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, port)),
+ .call = parse_qo,
+ },
+ /* Sub-level commands. */
+ [QUEUE_CREATE] = {
+ .name = "create",
+ .help = "create a flow rule",
+ .next = NEXT(NEXT_ENTRY(QUEUE_TEMPLATE_TABLE),
+ NEXT_ENTRY(COMMON_QUEUE_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, queue)),
+ .call = parse_qo,
+ },
+ [QUEUE_DESTROY] = {
+ .name = "destroy",
+ .help = "destroy a flow rule",
+ .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID),
+ NEXT_ENTRY(COMMON_QUEUE_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, queue)),
+ .call = parse_qo_destroy,
+ },
+ [QUEUE_INDIRECT_ACTION] = {
+ .name = "indirect_action",
+ .help = "queue indirect actions",
+ .next = NEXT(next_qia_subcmd, NEXT_ENTRY(COMMON_QUEUE_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, queue)),
+ .call = parse_qia,
+ },
+ /* Queue arguments. */
+ [QUEUE_TEMPLATE_TABLE] = {
+ .name = "template table",
+ .help = "specify table id",
+ .next = NEXT(NEXT_ENTRY(QUEUE_PATTERN_TEMPLATE),
+ NEXT_ENTRY(COMMON_TABLE_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer,
+ args.vc.table_id)),
+ .call = parse_qo,
+ },
+ [QUEUE_PATTERN_TEMPLATE] = {
+ .name = "pattern_template",
+ .help = "specify pattern template index",
+ .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE),
+ NEXT_ENTRY(COMMON_UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY(struct buffer,
+ args.vc.pat_templ_id)),
+ .call = parse_qo,
+ },
+ [QUEUE_ACTIONS_TEMPLATE] = {
+ .name = "actions_template",
+ .help = "specify actions template index",
+ .next = NEXT(NEXT_ENTRY(QUEUE_CREATE_POSTPONE),
+ NEXT_ENTRY(COMMON_UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY(struct buffer,
+ args.vc.act_templ_id)),
+ .call = parse_qo,
+ },
+ [QUEUE_CREATE_POSTPONE] = {
+ .name = "postpone",
+ .help = "postpone create operation",
+ .next = NEXT(NEXT_ENTRY(ITEM_PATTERN),
+ NEXT_ENTRY(COMMON_BOOLEAN)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, postpone)),
+ .call = parse_qo,
+ },
+ [QUEUE_DESTROY_POSTPONE] = {
+ .name = "postpone",
+ .help = "postpone destroy operation",
+ .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID),
+ NEXT_ENTRY(COMMON_BOOLEAN)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, postpone)),
+ .call = parse_qo_destroy,
+ },
+ [QUEUE_DESTROY_ID] = {
+ .name = "rule",
+ .help = "specify rule id to destroy",
+ .next = NEXT(next_queue_destroy_attr,
+ NEXT_ENTRY(COMMON_UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY_PTR(struct buffer,
+ args.destroy.rule)),
+ .call = parse_qo_destroy,
+ },
+ /* Queue indirect action arguments */
+ [QUEUE_INDIRECT_ACTION_CREATE] = {
+ .name = "create",
+ .help = "create indirect action",
+ .next = NEXT(next_qia_create_attr),
+ .call = parse_qia,
+ },
+ [QUEUE_INDIRECT_ACTION_UPDATE] = {
+ .name = "update",
+ .help = "update indirect action",
+ .next = NEXT(next_qia_update_attr,
+ NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)),
+ .call = parse_qia,
+ },
+ [QUEUE_INDIRECT_ACTION_DESTROY] = {
+ .name = "destroy",
+ .help = "destroy indirect action",
+ .next = NEXT(next_qia_destroy_attr),
+ .call = parse_qia_destroy,
+ },
+ /* Indirect action destroy arguments. */
+ [QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE] = {
+ .name = "postpone",
+ .help = "postpone destroy operation",
+ .next = NEXT(next_qia_destroy_attr,
+ NEXT_ENTRY(COMMON_BOOLEAN)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, postpone)),
+ },
+ [QUEUE_INDIRECT_ACTION_DESTROY_ID] = {
+ .name = "action_id",
+ .help = "specify a indirect action id to destroy",
+ .next = NEXT(next_qia_destroy_attr,
+ NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)),
+ .args = ARGS(ARGS_ENTRY_PTR(struct buffer,
+ args.ia_destroy.action_id)),
+ .call = parse_qia_destroy,
+ },
+ /* Indirect action update arguments. */
+ [QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE] = {
+ .name = "postpone",
+ .help = "postpone update operation",
+ .next = NEXT(next_qia_update_attr,
+ NEXT_ENTRY(COMMON_BOOLEAN)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, postpone)),
+ },
+ /* Indirect action create arguments. */
+ [QUEUE_INDIRECT_ACTION_CREATE_ID] = {
+ .name = "action_id",
+ .help = "specify a indirect action id to create",
+ .next = NEXT(next_qia_create_attr,
+ NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)),
+ },
+ [QUEUE_INDIRECT_ACTION_INGRESS] = {
+ .name = "ingress",
+ .help = "affect rule to ingress",
+ .next = NEXT(next_qia_create_attr),
+ .call = parse_qia,
+ },
+ [QUEUE_INDIRECT_ACTION_EGRESS] = {
+ .name = "egress",
+ .help = "affect rule to egress",
+ .next = NEXT(next_qia_create_attr),
+ .call = parse_qia,
+ },
+ [QUEUE_INDIRECT_ACTION_TRANSFER] = {
+ .name = "transfer",
+ .help = "affect rule to transfer",
+ .next = NEXT(next_qia_create_attr),
+ .call = parse_qia,
+ },
+ [QUEUE_INDIRECT_ACTION_CREATE_POSTPONE] = {
+ .name = "postpone",
+ .help = "postpone create operation",
+ .next = NEXT(next_qia_create_attr,
+ NEXT_ENTRY(COMMON_BOOLEAN)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, postpone)),
+ },
+ [QUEUE_INDIRECT_ACTION_SPEC] = {
+ .name = "action",
+ .help = "specify action to create indirect handle",
+ .next = NEXT(next_action),
+ },
+ /* Top-level command. */
+ [PUSH] = {
+ .name = "push",
+ .help = "push enqueued operations",
+ .next = NEXT(NEXT_ENTRY(PUSH_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, port)),
+ .call = parse_push,
+ },
+ /* Sub-level commands. */
+ [PUSH_QUEUE] = {
+ .name = "queue",
+ .help = "specify queue id",
+ .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, queue)),
+ },
+ /* Top-level command. */
+ [PULL] = {
+ .name = "pull",
+ .help = "pull flow operations results",
+ .next = NEXT(NEXT_ENTRY(PULL_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, port)),
+ .call = parse_pull,
+ },
+ /* Sub-level commands. */
+ [PULL_QUEUE] = {
+ .name = "queue",
+ .help = "specify queue id",
+ .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, queue)),
+ },
+ /* Top-level command. */
+ [INDIRECT_ACTION] = {
+ .name = "indirect_action",
+ .type = "{command} {port_id} [{arg} [...]]",
+ .help = "manage indirect actions",
+ .next = NEXT(next_ia_subcmd, NEXT_ENTRY(COMMON_PORT_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, port)),
+ .call = parse_ia,
+ },
+ /* Sub-level commands. */
+ [INDIRECT_ACTION_CREATE] = {
+ .name = "create",
+ .help = "create indirect action",
+ .next = NEXT(next_ia_create_attr),
+ .call = parse_ia,
+ },
+ [INDIRECT_ACTION_UPDATE] = {
+ .name = "update",
+ .help = "update indirect action",
+ .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_SPEC),
+ NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)),
+ .call = parse_ia,
+ },
+ [INDIRECT_ACTION_DESTROY] = {
+ .name = "destroy",
+ .help = "destroy indirect action",
+ .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_DESTROY_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, port)),
+ .call = parse_ia_destroy,
+ },
+ [INDIRECT_ACTION_QUERY] = {
+ .name = "query",
+ .help = "query indirect action",
+ .next = NEXT(NEXT_ENTRY(END),
+ NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)),
+ .call = parse_ia,
+ },
+ [VALIDATE] = {
+ .name = "validate",
+ .help = "check whether a flow rule can be created",
+ .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, port)),
+ .call = parse_vc,
+ },
+ [CREATE] = {
+ .name = "create",
+ .help = "create a flow rule",
+ .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, port)),
+ .call = parse_vc,
+ },
+ [DESTROY] = {
+ .name = "destroy",
+ .help = "destroy specific flow rules",
+ .next = NEXT(NEXT_ENTRY(DESTROY_RULE),
+ NEXT_ENTRY(COMMON_PORT_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, port)),
+ .call = parse_destroy,
+ },
+ [FLUSH] = {
+ .name = "flush",