From: Jasvinder Singh Date: Fri, 6 Jul 2018 17:21:09 +0000 (+0100) Subject: net/softnic: add command for pipeline table entries X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=ee19326a4b1ee47ee71cc58006e074f4ed9e5d88;p=dpdk.git net/softnic: add command for pipeline table entries Add cli commands for table entries in softnic pipeline objects. Signed-off-by: Cristian Dumitrescu Signed-off-by: Jasvinder Singh --- diff --git a/drivers/net/softnic/rte_eth_softnic_cli.c b/drivers/net/softnic/rte_eth_softnic_cli.c index 8b65a54330..59688ffaaa 100644 --- a/drivers/net/softnic/rte_eth_softnic_cli.c +++ b/drivers/net/softnic/rte_eth_softnic_cli.c @@ -7,6 +7,9 @@ #include #include +#include +#include + #include "rte_eth_softnic_internals.h" #include "parser.h" @@ -1593,272 +1596,2018 @@ cmd_softnic_pipeline_port_in_disable(struct pmd_internals *softnic, } /** - * thread pipeline enable + * ::= + * + * match + * acl + * priority + * ipv4 | ipv6 + * + * | array + * | hash + * raw + * | ipv4_5tuple + * | ipv6_5tuple + * | ipv4_addr + * | ipv6_addr + * | qinq + * | lpm + * ipv4 | ipv6 */ -static void -cmd_softnic_thread_pipeline_enable(struct pmd_internals *softnic, - char **tokens, +struct pkt_key_qinq { + uint16_t ethertype_svlan; + uint16_t svlan; + uint16_t ethertype_cvlan; + uint16_t cvlan; +} __attribute__((__packed__)); + +struct pkt_key_ipv4_5tuple { + uint8_t time_to_live; + uint8_t proto; + uint16_t hdr_checksum; + uint32_t sa; + uint32_t da; + uint16_t sp; + uint16_t dp; +} __attribute__((__packed__)); + +struct pkt_key_ipv6_5tuple { + uint16_t payload_length; + uint8_t proto; + uint8_t hop_limit; + uint8_t sa[16]; + uint8_t da[16]; + uint16_t sp; + uint16_t dp; +} __attribute__((__packed__)); + +struct pkt_key_ipv4_addr { + uint32_t addr; +} __attribute__((__packed__)); + +struct pkt_key_ipv6_addr { + uint8_t addr[16]; +} __attribute__((__packed__)); + +static uint32_t +parse_match(char **tokens, uint32_t n_tokens, char *out, - size_t out_size) + size_t out_size, + struct softnic_table_rule_match *m) { - char *pipeline_name; - uint32_t thread_id; - int status; - - if (n_tokens != 5) { - snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); - return; - } + memset(m, 0, sizeof(*m)); - if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) { - snprintf(out, out_size, MSG_ARG_INVALID, "thread_id"); - return; - } + if (n_tokens < 2) + return 0; - if (strcmp(tokens[2], "pipeline") != 0) { - snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline"); - return; + if (strcmp(tokens[0], "match") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match"); + return 0; } - pipeline_name = tokens[3]; + if (strcmp(tokens[1], "acl") == 0) { + if (n_tokens < 14) { + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return 0; + } - if (strcmp(tokens[4], "enable") != 0) { - snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable"); - return; - } + m->match_type = TABLE_ACL; - status = softnic_thread_pipeline_enable(softnic, thread_id, pipeline_name); - if (status) { - snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable"); - return; - } -} + if (strcmp(tokens[2], "priority") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "priority"); + return 0; + } -/** - * thread pipeline disable - */ -static void -cmd_softnic_thread_pipeline_disable(struct pmd_internals *softnic, - char **tokens, - uint32_t n_tokens, - char *out, - size_t out_size) -{ - char *pipeline_name; - uint32_t thread_id; - int status; + if (softnic_parser_read_uint32(&m->match.acl.priority, + tokens[3]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "priority"); + return 0; + } - if (n_tokens != 5) { - snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); - return; - } + if (strcmp(tokens[4], "ipv4") == 0) { + struct in_addr saddr, daddr; - if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) { - snprintf(out, out_size, MSG_ARG_INVALID, "thread_id"); - return; - } + m->match.acl.ip_version = 1; - if (strcmp(tokens[2], "pipeline") != 0) { - snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline"); - return; - } + if (softnic_parse_ipv4_addr(tokens[5], &saddr) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "sa"); + return 0; + } + m->match.acl.ipv4.sa = rte_be_to_cpu_32(saddr.s_addr); - pipeline_name = tokens[3]; + if (softnic_parse_ipv4_addr(tokens[7], &daddr) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "da"); + return 0; + } + m->match.acl.ipv4.da = rte_be_to_cpu_32(daddr.s_addr); + } else if (strcmp(tokens[4], "ipv6") == 0) { + struct in6_addr saddr, daddr; - if (strcmp(tokens[4], "disable") != 0) { - snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable"); - return; - } + m->match.acl.ip_version = 0; - status = softnic_thread_pipeline_disable(softnic, thread_id, pipeline_name); - if (status) { - snprintf(out, out_size, MSG_CMD_FAIL, - "thread pipeline disable"); - return; - } -} + if (softnic_parse_ipv6_addr(tokens[5], &saddr) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "sa"); + return 0; + } + memcpy(m->match.acl.ipv6.sa, saddr.s6_addr, 16); -void -softnic_cli_process(char *in, char *out, size_t out_size, void *arg) -{ - char *tokens[CMD_MAX_TOKENS]; - uint32_t n_tokens = RTE_DIM(tokens); - struct pmd_internals *softnic = arg; - int status; + if (softnic_parse_ipv6_addr(tokens[7], &daddr) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "da"); + return 0; + } + memcpy(m->match.acl.ipv6.da, daddr.s6_addr, 16); + } else { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, + "ipv4 or ipv6"); + return 0; + } - if (is_comment(in)) - return; + if (softnic_parser_read_uint32(&m->match.acl.sa_depth, + tokens[6]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "sa_depth"); + return 0; + } - status = softnic_parse_tokenize_string(in, tokens, &n_tokens); - if (status) { - snprintf(out, out_size, MSG_ARG_TOO_MANY, ""); - return; - } + if (softnic_parser_read_uint32(&m->match.acl.da_depth, + tokens[8]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "da_depth"); + return 0; + } - if (n_tokens == 0) - return; + if (softnic_parser_read_uint16(&m->match.acl.sp0, tokens[9]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "sp0"); + return 0; + } - if (strcmp(tokens[0], "mempool") == 0) { - cmd_mempool(softnic, tokens, n_tokens, out, out_size); - return; - } + if (softnic_parser_read_uint16(&m->match.acl.sp1, tokens[10]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "sp1"); + return 0; + } - if (strcmp(tokens[0], "link") == 0) { - cmd_link(softnic, tokens, n_tokens, out, out_size); - return; - } + if (softnic_parser_read_uint16(&m->match.acl.dp0, tokens[11]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "dp0"); + return 0; + } - if (strcmp(tokens[0], "swq") == 0) { - cmd_swq(softnic, tokens, n_tokens, out, out_size); - return; - } + if (softnic_parser_read_uint16(&m->match.acl.dp1, tokens[12]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "dp1"); + return 0; + } - if (strcmp(tokens[0], "tap") == 0) { - cmd_tap(softnic, tokens, n_tokens, out, out_size); - return; - } + if (softnic_parser_read_uint8(&m->match.acl.proto, tokens[13]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "proto"); + return 0; + } - if (strcmp(tokens[0], "port") == 0) { - cmd_port_in_action_profile(softnic, tokens, n_tokens, out, out_size); - return; - } + m->match.acl.proto_mask = 0xff; - if (strcmp(tokens[0], "table") == 0) { - cmd_table_action_profile(softnic, tokens, n_tokens, out, out_size); - return; - } + return 14; + } /* acl */ - if (strcmp(tokens[0], "pipeline") == 0) { - if (n_tokens >= 3 && - (strcmp(tokens[2], "period") == 0)) { - cmd_pipeline(softnic, tokens, n_tokens, out, out_size); - return; + if (strcmp(tokens[1], "array") == 0) { + if (n_tokens < 3) { + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return 0; } - if (n_tokens >= 5 && - (strcmp(tokens[2], "port") == 0) && - (strcmp(tokens[3], "in") == 0) && - (strcmp(tokens[4], "bsz") == 0)) { - cmd_pipeline_port_in(softnic, tokens, n_tokens, out, out_size); - return; - } + m->match_type = TABLE_ARRAY; - if (n_tokens >= 5 && - (strcmp(tokens[2], "port") == 0) && - (strcmp(tokens[3], "out") == 0) && - (strcmp(tokens[4], "bsz") == 0)) { - cmd_pipeline_port_out(softnic, tokens, n_tokens, out, out_size); - return; + if (softnic_parser_read_uint32(&m->match.array.pos, tokens[2]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "pos"); + return 0; } - if (n_tokens >= 4 && - (strcmp(tokens[2], "table") == 0) && - (strcmp(tokens[3], "match") == 0)) { - cmd_pipeline_table(softnic, tokens, n_tokens, out, out_size); - return; - } + return 3; + } /* array */ - if (n_tokens >= 6 && - (strcmp(tokens[2], "port") == 0) && - (strcmp(tokens[3], "in") == 0) && - (strcmp(tokens[5], "table") == 0)) { - cmd_pipeline_port_in_table(softnic, tokens, n_tokens, - out, out_size); - return; + if (strcmp(tokens[1], "hash") == 0) { + if (n_tokens < 3) { + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return 0; } - if (n_tokens >= 6 && - (strcmp(tokens[2], "port") == 0) && - (strcmp(tokens[3], "in") == 0) && - (strcmp(tokens[5], "enable") == 0)) { - cmd_softnic_pipeline_port_in_enable(softnic, tokens, n_tokens, - out, out_size); - return; - } + m->match_type = TABLE_HASH; - if (n_tokens >= 6 && - (strcmp(tokens[2], "port") == 0) && - (strcmp(tokens[3], "in") == 0) && - (strcmp(tokens[5], "disable") == 0)) { - cmd_softnic_pipeline_port_in_disable(softnic, tokens, n_tokens, - out, out_size); - return; - } - } + if (strcmp(tokens[2], "raw") == 0) { + uint32_t key_size = TABLE_RULE_MATCH_SIZE_MAX; - if (strcmp(tokens[0], "thread") == 0) { - if ((n_tokens >= 5) && - (strcmp(tokens[4], "enable") == 0)) { - cmd_softnic_thread_pipeline_enable(softnic, tokens, n_tokens, - out, out_size); - return; - } + if (n_tokens < 4) { + snprintf(out, out_size, MSG_ARG_MISMATCH, + tokens[0]); + return 0; + } - if ((n_tokens >= 5) && - (strcmp(tokens[4], "disable") == 0)) { - cmd_softnic_thread_pipeline_disable(softnic, tokens, n_tokens, - out, out_size); - return; - } - } + if (softnic_parse_hex_string(tokens[3], + m->match.hash.key, &key_size) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "key"); + return 0; + } - snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]); -} + return 4; + } /* hash raw */ -int -softnic_cli_script_process(struct pmd_internals *softnic, - const char *file_name, - size_t msg_in_len_max, - size_t msg_out_len_max) -{ - char *msg_in = NULL, *msg_out = NULL; - FILE *f = NULL; + if (strcmp(tokens[2], "ipv4_5tuple") == 0) { + struct pkt_key_ipv4_5tuple *ipv4 = + (struct pkt_key_ipv4_5tuple *)m->match.hash.key; + struct in_addr saddr, daddr; + uint16_t sp, dp; + uint8_t proto; - /* Check input arguments */ - if (file_name == NULL || - strlen(file_name) == 0 || - msg_in_len_max == 0 || - msg_out_len_max == 0) - return -EINVAL; + if (n_tokens < 8) { + snprintf(out, out_size, MSG_ARG_MISMATCH, + tokens[0]); + return 0; + } - msg_in = malloc(msg_in_len_max + 1); - msg_out = malloc(msg_out_len_max + 1); - if (msg_in == NULL || - msg_out == NULL) { - free(msg_out); - free(msg_in); - return -ENOMEM; - } + if (softnic_parse_ipv4_addr(tokens[3], &saddr) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "sa"); + return 0; + } - /* Open input file */ - f = fopen(file_name, "r"); - if (f == NULL) { - free(msg_out); - free(msg_in); - return -EIO; - } + if (softnic_parse_ipv4_addr(tokens[4], &daddr) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "da"); + return 0; + } - /* Read file */ - for ( ; ; ) { - if (fgets(msg_in, msg_in_len_max + 1, f) == NULL) - break; + if (softnic_parser_read_uint16(&sp, tokens[5]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "sp"); + return 0; + } - printf("%s", msg_in); - msg_out[0] = 0; + if (softnic_parser_read_uint16(&dp, tokens[6]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "dp"); + return 0; + } - softnic_cli_process(msg_in, - msg_out, - msg_out_len_max, - softnic); + if (softnic_parser_read_uint8(&proto, tokens[7]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, + "proto"); + return 0; + } - if (strlen(msg_out)) - printf("%s", msg_out); - } + ipv4->sa = saddr.s_addr; + ipv4->da = daddr.s_addr; + ipv4->sp = rte_cpu_to_be_16(sp); + ipv4->dp = rte_cpu_to_be_16(dp); + ipv4->proto = proto; + + return 8; + } /* hash ipv4_5tuple */ + + if (strcmp(tokens[2], "ipv6_5tuple") == 0) { + struct pkt_key_ipv6_5tuple *ipv6 = + (struct pkt_key_ipv6_5tuple *)m->match.hash.key; + struct in6_addr saddr, daddr; + uint16_t sp, dp; + uint8_t proto; + + if (n_tokens < 8) { + snprintf(out, out_size, MSG_ARG_MISMATCH, + tokens[0]); + return 0; + } - /* Close file */ - fclose(f); - free(msg_out); - free(msg_in); - return 0; + if (softnic_parse_ipv6_addr(tokens[3], &saddr) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "sa"); + return 0; + } + + if (softnic_parse_ipv6_addr(tokens[4], &daddr) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "da"); + return 0; + } + + if (softnic_parser_read_uint16(&sp, tokens[5]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "sp"); + return 0; + } + + if (softnic_parser_read_uint16(&dp, tokens[6]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "dp"); + return 0; + } + + if (softnic_parser_read_uint8(&proto, tokens[7]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, + "proto"); + return 0; + } + + memcpy(ipv6->sa, saddr.s6_addr, 16); + memcpy(ipv6->da, daddr.s6_addr, 16); + ipv6->sp = rte_cpu_to_be_16(sp); + ipv6->dp = rte_cpu_to_be_16(dp); + ipv6->proto = proto; + + return 8; + } /* hash ipv6_5tuple */ + + if (strcmp(tokens[2], "ipv4_addr") == 0) { + struct pkt_key_ipv4_addr *ipv4_addr = + (struct pkt_key_ipv4_addr *)m->match.hash.key; + struct in_addr addr; + + if (n_tokens < 4) { + snprintf(out, out_size, MSG_ARG_MISMATCH, + tokens[0]); + return 0; + } + + if (softnic_parse_ipv4_addr(tokens[3], &addr) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, + "addr"); + return 0; + } + + ipv4_addr->addr = addr.s_addr; + + return 4; + } /* hash ipv4_addr */ + + if (strcmp(tokens[2], "ipv6_addr") == 0) { + struct pkt_key_ipv6_addr *ipv6_addr = + (struct pkt_key_ipv6_addr *)m->match.hash.key; + struct in6_addr addr; + + if (n_tokens < 4) { + snprintf(out, out_size, MSG_ARG_MISMATCH, + tokens[0]); + return 0; + } + + if (softnic_parse_ipv6_addr(tokens[3], &addr) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, + "addr"); + return 0; + } + + memcpy(ipv6_addr->addr, addr.s6_addr, 16); + + return 4; + } /* hash ipv6_5tuple */ + + if (strcmp(tokens[2], "qinq") == 0) { + struct pkt_key_qinq *qinq = + (struct pkt_key_qinq *)m->match.hash.key; + uint16_t svlan, cvlan; + + if (n_tokens < 5) { + snprintf(out, out_size, MSG_ARG_MISMATCH, + tokens[0]); + return 0; + } + + if ((softnic_parser_read_uint16(&svlan, tokens[3]) != 0) || + svlan > 0xFFF) { + snprintf(out, out_size, MSG_ARG_INVALID, + "svlan"); + return 0; + } + + if ((softnic_parser_read_uint16(&cvlan, tokens[4]) != 0) || + cvlan > 0xFFF) { + snprintf(out, out_size, MSG_ARG_INVALID, + "cvlan"); + return 0; + } + + qinq->svlan = rte_cpu_to_be_16(svlan); + qinq->cvlan = rte_cpu_to_be_16(cvlan); + + return 5; + } /* hash qinq */ + + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return 0; + } /* hash */ + + if (strcmp(tokens[1], "lpm") == 0) { + if (n_tokens < 5) { + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return 0; + } + + m->match_type = TABLE_LPM; + + if (strcmp(tokens[2], "ipv4") == 0) { + struct in_addr addr; + + m->match.lpm.ip_version = 1; + + if (softnic_parse_ipv4_addr(tokens[3], &addr) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, + "addr"); + return 0; + } + + m->match.lpm.ipv4 = rte_be_to_cpu_32(addr.s_addr); + } else if (strcmp(tokens[2], "ipv6") == 0) { + struct in6_addr addr; + + m->match.lpm.ip_version = 0; + + if (softnic_parse_ipv6_addr(tokens[3], &addr) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, + "addr"); + return 0; + } + + memcpy(m->match.lpm.ipv6, addr.s6_addr, 16); + } else { + snprintf(out, out_size, MSG_ARG_MISMATCH, + "ipv4 or ipv6"); + return 0; + } + + if (softnic_parser_read_uint8(&m->match.lpm.depth, tokens[4]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "depth"); + return 0; + } + + return 5; + } /* lpm */ + + snprintf(out, out_size, MSG_ARG_MISMATCH, + "acl or array or hash or lpm"); + return 0; +} + +/** + * table_action ::= + * + * action + * fwd + * drop + * | port + * | meta + * | table + * [balance ... ] + * [meter + * tc0 meter policer g y r + * [tc1 meter policer g y r + * tc2 meter policer g y r + * tc3 meter policer g y r ]] + * [tm subport pipe ] + * [encap + * ether + * | vlan + * | qinq + * | mpls unicast | multicast + * + * label0