net: add rte prefix to ether structures
[dpdk.git] / examples / ip_pipeline / cli.c
index 552e0df..309b293 100644 (file)
@@ -245,7 +245,7 @@ static void
 print_link_info(struct link *link, char *out, size_t out_size)
 {
        struct rte_eth_stats stats;
-       struct ether_addr mac_addr;
+       struct rte_ether_addr mac_addr;
        struct rte_eth_link eth_link;
        uint16_t mtu;
 
@@ -790,7 +790,8 @@ cmd_kni(char **tokens,
 static const char cmd_cryptodev_help[] =
 "cryptodev <cryptodev_name>\n"
 "   dev <device_name> | dev_id <device_id>\n"
-"   queue <n_queues> <queue_size>\n";
+"   queue <n_queues> <queue_size>\n"
+"   max_sessions <n_sessions>";
 
 static void
 cmd_cryptodev(char **tokens,
@@ -802,7 +803,7 @@ cmd_cryptodev(char **tokens,
        char *name;
 
        memset(&params, 0, sizeof(params));
-       if (n_tokens != 7) {
+       if (n_tokens != 9) {
                snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
                return;
        }
@@ -825,7 +826,7 @@ cmd_cryptodev(char **tokens,
 
        if (strcmp(tokens[4], "queue")) {
                snprintf(out, out_size, MSG_ARG_NOT_FOUND,
-                       "4");
+                       "queue");
                return;
        }
 
@@ -841,6 +842,18 @@ cmd_cryptodev(char **tokens,
                return;
        }
 
+       if (strcmp(tokens[7], "max_sessions")) {
+               snprintf(out, out_size, MSG_ARG_NOT_FOUND,
+                       "max_sessions");
+               return;
+       }
+
+       if (parser_read_uint32(&params.session_pool_size, tokens[8]) < 0) {
+               snprintf(out, out_size, MSG_ARG_INVALID,
+                       "queue_size");
+               return;
+       }
+
        if (cryptodev_create(name, &params) == NULL) {
                snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
                return;
@@ -1022,7 +1035,7 @@ static const char cmd_table_action_profile_help[] =
 "       tc <n_tc>\n"
 "       stats none | pkts | bytes | both]\n"
 "   [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]\n"
-"   [encap ether | vlan | qinq | mpls | pppoe |\n"
+"   [encap ether | vlan | qinq | mpls | pppoe | qinq_pppoe \n"
 "       vxlan offset <ether_offset> ipv4 | ipv6 vlan on | off]\n"
 "   [nat src | dst\n"
 "       proto udp | tcp]\n"
@@ -1030,9 +1043,7 @@ static const char cmd_table_action_profile_help[] =
 "       stats none | pkts]\n"
 "   [stats pkts | bytes | both]\n"
 "   [time]\n"
-"   [sym_crypto dev <CRYPTODEV_NAME> offset <op_offset> "
-"       mempool_create <mempool_name>\n"
-"       mempool_init <mempool_name>]\n"
+"   [sym_crypto dev <CRYPTODEV_NAME> offset <op_offset>]\n"
 "   [tag]\n"
 "   [decap]\n";
 
@@ -1290,7 +1301,10 @@ cmd_table_action_profile(char **tokens,
 
                        p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VXLAN;
                        n_extra_tokens = 5;
-               } else {
+               } else if (strcmp(tokens[t0 + 1], "qinq_pppoe") == 0)
+                       p.encap.encap_mask =
+                               1LLU << RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE;
+               else {
                        snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
                        return;
                }
@@ -1404,13 +1418,10 @@ cmd_table_action_profile(char **tokens,
 
        if ((t0 < n_tokens) && (strcmp(tokens[t0], "sym_crypto") == 0)) {
                struct cryptodev *cryptodev;
-               struct mempool *mempool;
 
-               if (n_tokens < t0 + 9 ||
+               if (n_tokens < t0 + 5 ||
                                strcmp(tokens[t0 + 1], "dev") ||
-                               strcmp(tokens[t0 + 3], "offset") ||
-                               strcmp(tokens[t0 + 5], "mempool_create") ||
-                               strcmp(tokens[t0 + 7], "mempool_init")) {
+                               strcmp(tokens[t0 + 3], "offset")) {
                        snprintf(out, out_size, MSG_ARG_MISMATCH,
                                "table action profile sym_crypto");
                        return;
@@ -1432,25 +1443,12 @@ cmd_table_action_profile(char **tokens,
                        return;
                }
 
-               mempool = mempool_find(tokens[t0 + 6]);
-               if (mempool == NULL) {
-                       snprintf(out, out_size, MSG_ARG_INVALID,
-                               "table action profile sym_crypto");
-                       return;
-               }
-               p.sym_crypto.mp_create = mempool->m;
-
-               mempool = mempool_find(tokens[t0 + 8]);
-               if (mempool == NULL) {
-                       snprintf(out, out_size, MSG_ARG_INVALID,
-                               "table action profile sym_crypto");
-                       return;
-               }
-               p.sym_crypto.mp_init = mempool->m;
+               p.sym_crypto.mp_create = cryptodev->mp_create;
+               p.sym_crypto.mp_init = cryptodev->mp_init;
 
                p.action_mask |= 1LLU << RTE_TABLE_ACTION_SYM_CRYPTO;
 
-               t0 += 9;
+               t0 += 5;
        } /* sym_crypto */
 
        if ((t0 < n_tokens) && (strcmp(tokens[t0], "tag") == 0)) {
@@ -3090,6 +3088,7 @@ parse_match(char **tokens,
  *       ether <da> <sa>
  *       | vlan <da> <sa> <pcp> <dei> <vid>
  *       | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
+ *       | qinq_pppoe <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid> <session_id>
  *       | mpls unicast | multicast
  *          <da> <sa>
  *          label0 <label> <tc> <ttl>
@@ -3238,11 +3237,11 @@ parse_table_action_meter_tc(char **tokens,
                parser_read_uint32(&mtr->meter_profile_id, tokens[1]) ||
                strcmp(tokens[2], "policer") ||
                strcmp(tokens[3], "g") ||
-               parse_policer_action(tokens[4], &mtr->policer[e_RTE_METER_GREEN]) ||
+               parse_policer_action(tokens[4], &mtr->policer[RTE_COLOR_GREEN]) ||
                strcmp(tokens[5], "y") ||
-               parse_policer_action(tokens[6], &mtr->policer[e_RTE_METER_YELLOW]) ||
+               parse_policer_action(tokens[6], &mtr->policer[RTE_COLOR_YELLOW]) ||
                strcmp(tokens[7], "r") ||
-               parse_policer_action(tokens[8], &mtr->policer[e_RTE_METER_RED]))
+               parse_policer_action(tokens[8], &mtr->policer[RTE_COLOR_RED]))
                return 0;
 
        return 9;
@@ -3391,6 +3390,44 @@ parse_table_action_encap(char **tokens,
                return 1 + 9;
        }
 
+       /* qinq_pppoe */
+       if (n_tokens && (strcmp(tokens[0], "qinq_pppoe") == 0)) {
+               uint32_t svlan_pcp, svlan_dei, svlan_vid;
+               uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
+
+               if ((n_tokens < 10) ||
+                       parse_mac_addr(tokens[1],
+                               &a->encap.qinq_pppoe.ether.da) ||
+                       parse_mac_addr(tokens[2],
+                               &a->encap.qinq_pppoe.ether.sa) ||
+                       parser_read_uint32(&svlan_pcp, tokens[3]) ||
+                       (svlan_pcp > 0x7) ||
+                       parser_read_uint32(&svlan_dei, tokens[4]) ||
+                       (svlan_dei > 0x1) ||
+                       parser_read_uint32(&svlan_vid, tokens[5]) ||
+                       (svlan_vid > 0xFFF) ||
+                       parser_read_uint32(&cvlan_pcp, tokens[6]) ||
+                       (cvlan_pcp > 0x7) ||
+                       parser_read_uint32(&cvlan_dei, tokens[7]) ||
+                       (cvlan_dei > 0x1) ||
+                       parser_read_uint32(&cvlan_vid, tokens[8]) ||
+                       (cvlan_vid > 0xFFF) ||
+                       parser_read_uint16(&a->encap.qinq_pppoe.pppoe.session_id,
+                               tokens[9]))
+                       return 0;
+
+               a->encap.qinq_pppoe.svlan.pcp = svlan_pcp & 0x7;
+               a->encap.qinq_pppoe.svlan.dei = svlan_dei & 0x1;
+               a->encap.qinq_pppoe.svlan.vid = svlan_vid & 0xFFF;
+               a->encap.qinq_pppoe.cvlan.pcp = cvlan_pcp & 0x7;
+               a->encap.qinq_pppoe.cvlan.dei = cvlan_dei & 0x1;
+               a->encap.qinq_pppoe.cvlan.vid = cvlan_vid & 0xFFF;
+               a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE;
+               a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
+               return 1 + 10;
+
+       }
+
        /* mpls */
        if (n_tokens && (strcmp(tokens[0], "mpls") == 0)) {
                uint32_t label, tc, ttl;
@@ -4739,6 +4776,420 @@ cmd_pipeline_table_rule_delete_default(char **tokens,
        }
 }
 
+static void
+ether_addr_show(FILE *f, struct rte_ether_addr *addr)
+{
+       fprintf(f, "%02x:%02x:%02x:%02x:%02x:%02x",
+               (uint32_t)addr->addr_bytes[0], (uint32_t)addr->addr_bytes[1],
+               (uint32_t)addr->addr_bytes[2], (uint32_t)addr->addr_bytes[3],
+               (uint32_t)addr->addr_bytes[4], (uint32_t)addr->addr_bytes[5]);
+}
+
+static void
+ipv4_addr_show(FILE *f, uint32_t addr)
+{
+       fprintf(f, "%u.%u.%u.%u",
+               addr >> 24,
+               (addr >> 16) & 0xFF,
+               (addr >> 8) & 0xFF,
+               addr & 0xFF);
+}
+
+static void
+ipv6_addr_show(FILE *f, uint8_t *addr)
+{
+       fprintf(f, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:"
+               "%02x%02x:%02x%02x:%02x%02x:%02x%02x:",
+               (uint32_t)addr[0], (uint32_t)addr[1],
+               (uint32_t)addr[2], (uint32_t)addr[3],
+               (uint32_t)addr[4], (uint32_t)addr[5],
+               (uint32_t)addr[6], (uint32_t)addr[7],
+               (uint32_t)addr[8], (uint32_t)addr[9],
+               (uint32_t)addr[10], (uint32_t)addr[11],
+               (uint32_t)addr[12], (uint32_t)addr[13],
+               (uint32_t)addr[14], (uint32_t)addr[15]);
+}
+
+static const char *
+policer_action_string(enum rte_table_action_policer action) {
+       switch (action) {
+               case RTE_TABLE_ACTION_POLICER_COLOR_GREEN: return "G";
+               case RTE_TABLE_ACTION_POLICER_COLOR_YELLOW: return "Y";
+               case RTE_TABLE_ACTION_POLICER_COLOR_RED: return "R";
+               case RTE_TABLE_ACTION_POLICER_DROP: return "D";
+               default: return "?";
+       }
+}
+
+static int
+table_rule_show(const char *pipeline_name,
+       uint32_t table_id,
+       const char *file_name)
+{
+       struct pipeline *p;
+       struct table *table;
+       struct table_rule *rule;
+       FILE *f = NULL;
+       uint32_t i;
+
+       /* Check input params. */
+       if ((pipeline_name == NULL) ||
+               (file_name == NULL))
+               return -1;
+
+       p = pipeline_find(pipeline_name);
+       if ((p == NULL) ||
+               (table_id >= p->n_tables))
+               return -1;
+
+       table = &p->table[table_id];
+
+       /* Open file. */
+       f = fopen(file_name, "w");
+       if (f == NULL)
+               return -1;
+
+       /* Write table rules to file. */
+       TAILQ_FOREACH(rule, &table->rules, node) {
+               struct table_rule_match *m = &rule->match;
+               struct table_rule_action *a = &rule->action;
+
+               fprintf(f, "match ");
+               switch (m->match_type) {
+               case TABLE_ACL:
+                       fprintf(f, "acl priority %u ",
+                               m->match.acl.priority);
+
+                       fprintf(f, m->match.acl.ip_version ? "ipv4 " : "ipv6 ");
+
+                       if (m->match.acl.ip_version)
+                               ipv4_addr_show(f, m->match.acl.ipv4.sa);
+                       else
+                               ipv6_addr_show(f, m->match.acl.ipv6.sa);
+
+                       fprintf(f, "%u",        m->match.acl.sa_depth);
+
+                       if (m->match.acl.ip_version)
+                               ipv4_addr_show(f, m->match.acl.ipv4.da);
+                       else
+                               ipv6_addr_show(f, m->match.acl.ipv6.da);
+
+                       fprintf(f, "%u",        m->match.acl.da_depth);
+
+                       fprintf(f, "%u %u %u %u %u ",
+                               (uint32_t)m->match.acl.sp0,
+                               (uint32_t)m->match.acl.sp1,
+                               (uint32_t)m->match.acl.dp0,
+                               (uint32_t)m->match.acl.dp1,
+                               (uint32_t)m->match.acl.proto);
+                       break;
+
+               case TABLE_ARRAY:
+                       fprintf(f, "array %u ",
+                               m->match.array.pos);
+                       break;
+
+               case TABLE_HASH:
+                       fprintf(f, "hash raw ");
+                       for (i = 0; i < table->params.match.hash.key_size; i++)
+                               fprintf(f, "%02x", m->match.hash.key[i]);
+                       fprintf(f, " ");
+                       break;
+
+               case TABLE_LPM:
+                       fprintf(f, "lpm ");
+
+                       fprintf(f, m->match.lpm.ip_version ? "ipv4 " : "ipv6 ");
+
+                       if (m->match.acl.ip_version)
+                               ipv4_addr_show(f, m->match.lpm.ipv4);
+                       else
+                               ipv6_addr_show(f, m->match.lpm.ipv6);
+
+                       fprintf(f, "%u ",
+                               (uint32_t)m->match.lpm.depth);
+                       break;
+
+               default:
+                       fprintf(f, "unknown ");
+               }
+
+               fprintf(f, "action ");
+               if (a->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
+                       fprintf(f, "fwd ");
+                       switch (a->fwd.action) {
+                       case RTE_PIPELINE_ACTION_DROP:
+                               fprintf(f, "drop ");
+                               break;
+
+                       case RTE_PIPELINE_ACTION_PORT:
+                               fprintf(f, "port %u ", a->fwd.id);
+                               break;
+
+                       case RTE_PIPELINE_ACTION_PORT_META:
+                               fprintf(f, "meta ");
+                               break;
+
+                       case RTE_PIPELINE_ACTION_TABLE:
+                       default:
+                               fprintf(f, "table %u ", a->fwd.id);
+                       }
+               }
+
+               if (a->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
+                       fprintf(f, "balance ");
+                       for (i = 0; i < RTE_DIM(a->lb.out); i++)
+                               fprintf(f, "%u ", a->lb.out[i]);
+               }
+
+               if (a->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
+                       fprintf(f, "mtr ");
+                       for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++)
+                               if (a->mtr.tc_mask & (1 << i)) {
+                                       struct rte_table_action_mtr_tc_params *p =
+                                               &a->mtr.mtr[i];
+                                       enum rte_table_action_policer ga =
+                                               p->policer[RTE_COLOR_GREEN];
+                                       enum rte_table_action_policer ya =
+                                               p->policer[RTE_COLOR_YELLOW];
+                                       enum rte_table_action_policer ra =
+                                               p->policer[RTE_COLOR_RED];
+
+                                       fprintf(f, "tc%u meter %u policer g %s y %s r %s ",
+                                               i,
+                                               a->mtr.mtr[i].meter_profile_id,
+                                               policer_action_string(ga),
+                                               policer_action_string(ya),
+                                               policer_action_string(ra));
+                               }
+               }
+
+               if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TM))
+                       fprintf(f, "tm subport %u pipe %u ",
+                               a->tm.subport_id,
+                               a->tm.pipe_id);
+
+               if (a->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
+                       fprintf(f, "encap ");
+                       switch (a->encap.type) {
+                       case RTE_TABLE_ACTION_ENCAP_ETHER:
+                               fprintf(f, "ether ");
+                               ether_addr_show(f, &a->encap.ether.ether.da);
+                               fprintf(f, " ");
+                               ether_addr_show(f, &a->encap.ether.ether.sa);
+                               fprintf(f, " ");
+                               break;
+
+                       case RTE_TABLE_ACTION_ENCAP_VLAN:
+                               fprintf(f, "vlan ");
+                               ether_addr_show(f, &a->encap.vlan.ether.da);
+                               fprintf(f, " ");
+                               ether_addr_show(f, &a->encap.vlan.ether.sa);
+                               fprintf(f, " pcp %u dei %u vid %u ",
+                                       a->encap.vlan.vlan.pcp,
+                                       a->encap.vlan.vlan.dei,
+                                       a->encap.vlan.vlan.vid);
+                               break;
+
+                       case RTE_TABLE_ACTION_ENCAP_QINQ:
+                               fprintf(f, "qinq ");
+                               ether_addr_show(f, &a->encap.qinq.ether.da);
+                               fprintf(f, " ");
+                               ether_addr_show(f, &a->encap.qinq.ether.sa);
+                               fprintf(f, " pcp %u dei %u vid %u pcp %u dei %u vid %u ",
+                                       a->encap.qinq.svlan.pcp,
+                                       a->encap.qinq.svlan.dei,
+                                       a->encap.qinq.svlan.vid,
+                                       a->encap.qinq.cvlan.pcp,
+                                       a->encap.qinq.cvlan.dei,
+                                       a->encap.qinq.cvlan.vid);
+                               break;
+
+                       case RTE_TABLE_ACTION_ENCAP_MPLS:
+                               fprintf(f, "mpls %s ", (a->encap.mpls.unicast) ?
+                                       "unicast " : "multicast ");
+                               ether_addr_show(f, &a->encap.mpls.ether.da);
+                               fprintf(f, " ");
+                               ether_addr_show(f, &a->encap.mpls.ether.sa);
+                               fprintf(f, " ");
+                               for (i = 0; i < a->encap.mpls.mpls_count; i++) {
+                                       struct rte_table_action_mpls_hdr *l =
+                                               &a->encap.mpls.mpls[i];
+
+                                       fprintf(f, "label%u %u %u %u ",
+                                               i,
+                                               l->label,
+                                               l->tc,
+                                               l->ttl);
+                               }
+                               break;
+
+                       case RTE_TABLE_ACTION_ENCAP_PPPOE:
+                               fprintf(f, "pppoe ");
+                               ether_addr_show(f, &a->encap.pppoe.ether.da);
+                               fprintf(f, " ");
+                               ether_addr_show(f, &a->encap.pppoe.ether.sa);
+                               fprintf(f, " %u ", a->encap.pppoe.pppoe.session_id);
+                               break;
+
+                       case RTE_TABLE_ACTION_ENCAP_VXLAN:
+                               fprintf(f, "vxlan ether ");
+                               ether_addr_show(f, &a->encap.vxlan.ether.da);
+                               fprintf(f, " ");
+                               ether_addr_show(f, &a->encap.vxlan.ether.sa);
+                               if (table->ap->params.encap.vxlan.vlan)
+                                       fprintf(f, " vlan pcp %u dei %u vid %u ",
+                                               a->encap.vxlan.vlan.pcp,
+                                               a->encap.vxlan.vlan.dei,
+                                               a->encap.vxlan.vlan.vid);
+                               if (table->ap->params.encap.vxlan.ip_version) {
+                                       fprintf(f, " ipv4 ");
+                                       ipv4_addr_show(f, a->encap.vxlan.ipv4.sa);
+                                       fprintf(f, " ");
+                                       ipv4_addr_show(f, a->encap.vxlan.ipv4.da);
+                                       fprintf(f, " %u %u ",
+                                               (uint32_t)a->encap.vxlan.ipv4.dscp,
+                                               (uint32_t)a->encap.vxlan.ipv4.ttl);
+                               } else {
+                                       fprintf(f, " ipv6 ");
+                                       ipv6_addr_show(f, a->encap.vxlan.ipv6.sa);
+                                       fprintf(f, " ");
+                                       ipv6_addr_show(f, a->encap.vxlan.ipv6.da);
+                                       fprintf(f, " %u %u %u ",
+                                               a->encap.vxlan.ipv6.flow_label,
+                                               (uint32_t)a->encap.vxlan.ipv6.dscp,
+                                               (uint32_t)a->encap.vxlan.ipv6.hop_limit);
+                                       fprintf(f, " udp %u %u vxlan %u ",
+                                               a->encap.vxlan.udp.sp,
+                                               a->encap.vxlan.udp.dp,
+                                               a->encap.vxlan.vxlan.vni);
+                               }
+                               break;
+
+                       default:
+                               fprintf(f, "unknown ");
+                       }
+               }
+
+               if (a->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
+                       fprintf(f, "nat %s ", (a->nat.ip_version) ? "ipv4 " : "ipv6 ");
+                       if (a->nat.ip_version)
+                               ipv4_addr_show(f, a->nat.addr.ipv4);
+                       else
+                               ipv6_addr_show(f, a->nat.addr.ipv6);
+                       fprintf(f, " %u ", (uint32_t)(a->nat.port));
+               }
+
+               if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TTL))
+                       fprintf(f, "ttl %s ", (a->ttl.decrement) ? "dec" : "keep");
+
+               if (a->action_mask & (1LLU << RTE_TABLE_ACTION_STATS))
+                       fprintf(f, "stats ");
+
+               if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TIME))
+                       fprintf(f, "time ");
+
+               if (a->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO))
+                       fprintf(f, "sym_crypto ");
+
+               if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TAG))
+                       fprintf(f, "tag %u ", a->tag.tag);
+
+               if (a->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP))
+                       fprintf(f, "decap %u ", a->decap.n);
+
+               /* end */
+               fprintf(f, "\n");
+       }
+
+       /* Write table default rule to file. */
+       if (table->rule_default) {
+               struct table_rule_action *a = &table->rule_default->action;
+
+               fprintf(f, "# match default action fwd ");
+
+               switch (a->fwd.action) {
+               case RTE_PIPELINE_ACTION_DROP:
+                       fprintf(f, "drop ");
+                       break;
+
+               case RTE_PIPELINE_ACTION_PORT:
+                       fprintf(f, "port %u ", a->fwd.id);
+                       break;
+
+               case RTE_PIPELINE_ACTION_PORT_META:
+                       fprintf(f, "meta ");
+                       break;
+
+               case RTE_PIPELINE_ACTION_TABLE:
+               default:
+                       fprintf(f, "table %u ", a->fwd.id);
+               }
+       } else
+               fprintf(f, "# match default action fwd drop ");
+
+       fprintf(f, "\n");
+
+       /* Close file. */
+       fclose(f);
+
+       return 0;
+}
+
+static const char cmd_pipeline_table_rule_show_help[] =
+"pipeline <pipeline_name> table <table_id> rule show\n"
+"     file <file_name>\n";
+
+static void
+cmd_pipeline_table_rule_show(char **tokens,
+       uint32_t n_tokens,
+       char *out,
+       size_t out_size)
+{
+       char *file_name = NULL, *pipeline_name;
+       uint32_t table_id;
+       int status;
+
+       if (n_tokens != 8) {
+               snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+               return;
+       }
+
+       pipeline_name = tokens[1];
+
+       if (strcmp(tokens[2], "table") != 0) {
+               snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
+               return;
+       }
+
+       if (parser_read_uint32(&table_id, tokens[3]) != 0) {
+               snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
+               return;
+       }
+
+       if (strcmp(tokens[4], "rule") != 0) {
+               snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
+               return;
+       }
+
+       if (strcmp(tokens[5], "show") != 0) {
+               snprintf(out, out_size, MSG_ARG_NOT_FOUND, "show");
+               return;
+       }
+
+       if (strcmp(tokens[6], "file") != 0) {
+               snprintf(out, out_size, MSG_ARG_NOT_FOUND, "file");
+               return;
+       }
+
+       file_name = tokens[7];
+
+       status = table_rule_show(pipeline_name, table_id, file_name);
+       if (status) {
+               snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
+               return;
+       }
+}
 
 static const char cmd_pipeline_table_rule_stats_read_help[] =
 "pipeline <pipeline_name> table <table_id> rule read stats [clear]\n"
@@ -5195,7 +5646,7 @@ load_dscp_table(struct rte_table_action_dscp_table *dscp_table,
        for (dscp = 0, l = 1; ; l++) {
                char line[64];
                char *tokens[3];
-               enum rte_meter_color color;
+               enum rte_color color;
                uint32_t tc_id, tc_queue_id, n_tokens = RTE_DIM(tokens);
 
                if (fgets(line, sizeof(line), f) == NULL)
@@ -5228,17 +5679,17 @@ load_dscp_table(struct rte_table_action_dscp_table *dscp_table,
                switch (tokens[2][0]) {
                case 'g':
                case 'G':
-                       color = e_RTE_METER_GREEN;
+                       color = RTE_COLOR_GREEN;
                        break;
 
                case 'y':
                case 'Y':
-                       color = e_RTE_METER_YELLOW;
+                       color = RTE_COLOR_YELLOW;
                        break;
 
                case 'r':
                case 'R':
-                       color = e_RTE_METER_RED;
+                       color = RTE_COLOR_RED;
                        break;
 
                default:
@@ -5617,6 +6068,7 @@ cmd_help(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
                        "\tpipeline table rule add bulk\n"
                        "\tpipeline table rule delete\n"
                        "\tpipeline table rule delete default\n"
+                       "\tpipeline table rule show\n"
                        "\tpipeline table rule stats read\n"
                        "\tpipeline table meter profile add\n"
                        "\tpipeline table meter profile delete\n"
@@ -5831,6 +6283,14 @@ cmd_help(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
                        return;
                }
 
+               if ((n_tokens == 4) &&
+                       (strcmp(tokens[2], "rule") == 0) &&
+                       (strcmp(tokens[3], "show") == 0)) {
+                       snprintf(out, out_size, "\n%s\n",
+                               cmd_pipeline_table_rule_show_help);
+                       return;
+               }
+
                if ((n_tokens == 5) &&
                        (strcmp(tokens[2], "rule") == 0) &&
                        (strcmp(tokens[3], "stats") == 0) &&
@@ -6135,6 +6595,15 @@ cli_process(char *in, char *out, size_t out_size)
                        return;
                }
 
+               if ((n_tokens >= 6) &&
+                       (strcmp(tokens[2], "table") == 0) &&
+                       (strcmp(tokens[4], "rule") == 0) &&
+                       (strcmp(tokens[5], "show") == 0)) {
+                       cmd_pipeline_table_rule_show(tokens, n_tokens,
+                               out, out_size);
+                       return;
+               }
+
                if ((n_tokens >= 7) &&
                        (strcmp(tokens[2], "table") == 0) &&
                        (strcmp(tokens[4], "rule") == 0) &&
@@ -6409,20 +6878,26 @@ cli_rule_file_process(const char *file_name,
        return 0;
 
 cli_rule_file_process_free:
-       *rule_list = NULL;
-       *n_rules = rule_id;
-       *line_number = line_id;
+       if (rule_list != NULL)
+               *rule_list = NULL;
 
-       for ( ; ; ) {
-               struct table_rule *rule;
+       if (n_rules != NULL)
+               *n_rules = rule_id;
 
-               rule = TAILQ_FIRST(list);
-               if (rule == NULL)
-                       break;
+       if (line_number != NULL)
+               *line_number = line_id;
 
-               TAILQ_REMOVE(list, rule, node);
-               free(rule);
-       }
+       if (list != NULL)
+               for ( ; ; ) {
+                       struct table_rule *rule;
+
+                       rule = TAILQ_FIRST(list);
+                       if (rule == NULL)
+                               break;
+
+                       TAILQ_REMOVE(list, rule, node);
+                       free(rule);
+               }
 
        if (f)
                fclose(f);