diff --git a/lib/librte_telemetry/Makefile b/lib/librte_telemetry/Makefile
index 0d61361..95c7296 100644
--- a/lib/librte_telemetry/Makefile
+++ b/lib/librte_telemetry/Makefile
@@ -21,6 +21,7 @@ LIBABIVER := 1
 
 # library source files
 SRCS-$(CONFIG_RTE_LIBRTE_TELEMETRY) := rte_telemetry.c
+SRCS-$(CONFIG_RTE_LIBRTE_TELEMETRY) += rte_telemetry_parser.c
 
 # export include files
 SYMLINK-$(CONFIG_RTE_LIBRTE_TELEMETRY)-include := rte_telemetry.h
diff --git a/lib/librte_telemetry/meson.build b/lib/librte_telemetry/meson.build
index 0ccfa36..7450f96 100644
--- a/lib/librte_telemetry/meson.build
+++ b/lib/librte_telemetry/meson.build
@@ -1,8 +1,8 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2018 Intel Corporation
 
-sources = files('rte_telemetry.c')
-headers = files('rte_telemetry.h', 'rte_telemetry_internal.h')
+sources = files('rte_telemetry.c', 'rte_telemetry_parser.c')
+headers = files('rte_telemetry.h', 'rte_telemetry_internal.h', 'rte_telemetry_parser.h')
 deps += ['metrics', 'ethdev']
 cflags += '-DALLOW_EXPERIMENTAL_API'
 jansson = cc.find_library('jansson', required: true)
diff --git a/lib/librte_telemetry/rte_telemetry.c b/lib/librte_telemetry/rte_telemetry.c
index 15292de..d9b67d4 100644
--- a/lib/librte_telemetry/rte_telemetry.c
+++ b/lib/librte_telemetry/rte_telemetry.c
@@ -17,6 +17,7 @@
 
 #include "rte_telemetry.h"
 #include "rte_telemetry_internal.h"
+#include "rte_telemetry_parser.h"
 
 #define BUF_SIZE 1024
 #define ACTION_POST 1
@@ -283,6 +284,7 @@ rte_telemetry_accept_new_client(struct telemetry_impl *telemetry)
 static int32_t
 rte_telemetry_read_client_sockets(struct telemetry_impl *telemetry)
 {
+	int ret;
 	telemetry_client *client;
 	char client_buf[BUF_SIZE];
 	int bytes;
@@ -293,6 +295,12 @@ rte_telemetry_read_client_sockets(struct telemetry_impl *telemetry)
 		if (bytes > 0) {
 			client_buf[bytes] = '\0';
 			telemetry->request_client = client;
+			ret = rte_telemetry_parse(telemetry, client_buf);
+			if (ret < 0) {
+				TELEMETRY_LOG_WARN("Parse socket input failed: %i",
+						ret);
+				return -1;
+			}
 		}
 	}
 
diff --git a/lib/librte_telemetry/rte_telemetry_internal.h b/lib/librte_telemetry/rte_telemetry_internal.h
index e3292cf..86a5ba1 100644
--- a/lib/librte_telemetry/rte_telemetry_internal.h
+++ b/lib/librte_telemetry/rte_telemetry_internal.h
@@ -43,6 +43,11 @@ typedef struct telemetry_impl {
 	int register_fail_count;
 } telemetry_impl;
 
+enum rte_telemetry_parser_actions {
+	ACTION_GET = 0,
+	ACTION_DELETE = 2
+};
+
 int32_t
 rte_telemetry_parse_client_message(struct telemetry_impl *telemetry, char *buf);
 
@@ -58,4 +63,12 @@ int32_t
 rte_telemetry_unregister_client(struct telemetry_impl *telemetry,
 	const char *client_path);
 
+/**
+ * This is a wrapper for the ethdev api rte_eth_find_next().
+ * If rte_eth_find_next() returns the same port id that we passed it,
+ * then we know that that port is active.
+ */
+int32_t
+rte_telemetry_is_port_active(int port_id);
+
 #endif
diff --git a/lib/librte_telemetry/rte_telemetry_parser.c b/lib/librte_telemetry/rte_telemetry_parser.c
new file mode 100644
index 0000000..6bc4c6d
--- /dev/null
+++ b/lib/librte_telemetry/rte_telemetry_parser.c
@@ -0,0 +1,569 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <jansson.h>
+
+#include <rte_metrics.h>
+#include <rte_common.h>
+#include <rte_ethdev.h>
+
+#include "rte_telemetry_internal.h"
+
+typedef int (*command_func)(struct telemetry_impl *, int, json_t *);
+
+struct rte_telemetry_command {
+	char *text;
+	command_func fn;
+} command;
+
+static int32_t
+rte_telemetry_command_clients(struct telemetry_impl *telemetry, int action,
+	json_t *data)
+{
+	int ret;
+
+	if (telemetry == NULL) {
+		TELEMETRY_LOG_ERR("Invalid telemetry argument");
+		return -1;
+	}
+
+	if (action != ACTION_DELETE) {
+		TELEMETRY_LOG_WARN("Invalid action for this command");
+		goto einval_fail;
+	}
+
+	if (!json_is_object(data)) {
+		TELEMETRY_LOG_WARN("Invalid data provided for this command");
+		goto einval_fail;
+	}
+
+	json_t *client_path = json_object_get(data, "client_path");
+	if (!json_is_string(client_path)) {
+		TELEMETRY_LOG_WARN("Command value is not a string");
+		goto einval_fail;
+	}
+
+	ret = rte_telemetry_unregister_client(telemetry,
+			json_string_value(client_path));
+	if (ret < 0) {
+		TELEMETRY_LOG_ERR("Could not unregister client");
+		goto einval_fail;
+	}
+
+	return 0;
+
+einval_fail:
+	ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+	if (ret < 0)
+		TELEMETRY_LOG_ERR("Could not send error");
+	return -1;
+}
+
+static int32_t
+rte_telemetry_command_ports(struct telemetry_impl *telemetry, int action,
+	json_t *data)
+{
+	int ret;
+
+	if (telemetry == NULL) {
+		TELEMETRY_LOG_ERR("Invalid telemetry argument");
+		return -1;
+	}
+
+	if (!json_is_null(data)) {
+		TELEMETRY_LOG_WARN("Data should be NULL JSON object for 'ports' command");
+		goto einval_fail;
+	}
+
+	if (action != ACTION_GET) {
+		TELEMETRY_LOG_WARN("Invalid action for this command");
+		goto einval_fail;
+	}
+
+	return 0;
+
+einval_fail:
+	ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+	if (ret < 0)
+		TELEMETRY_LOG_ERR("Could not send error");
+	return -1;
+}
+
+static int32_t
+rte_telemetry_command_ports_details(struct telemetry_impl *telemetry,
+	int action, json_t *data)
+{
+	json_t *value, *port_ids_json = json_object_get(data, "ports");
+	uint64_t num_port_ids = json_array_size(port_ids_json);
+	int ret, port_ids[num_port_ids];
+	RTE_SET_USED(port_ids);
+	size_t index;
+
+	if (telemetry == NULL) {
+		TELEMETRY_LOG_ERR("Invalid telemetry argument");
+		return -1;
+	}
+
+	if (action != ACTION_GET) {
+		TELEMETRY_LOG_WARN("Invalid action for this command");
+		goto einval_fail;
+	}
+
+	if (!json_is_object(data)) {
+		TELEMETRY_LOG_WARN("Invalid data provided for this command");
+		goto einval_fail;
+	}
+
+	if (!json_is_array(port_ids_json)) {
+		TELEMETRY_LOG_WARN("Invalid Port ID array");
+		goto einval_fail;
+	}
+
+	json_array_foreach(port_ids_json, index, value) {
+		if (!json_is_integer(value)) {
+			TELEMETRY_LOG_WARN("Port ID given is invalid");
+			goto einval_fail;
+		}
+		port_ids[index] = json_integer_value(value);
+	}
+
+	return 0;
+
+einval_fail:
+	ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+	if (ret < 0)
+		TELEMETRY_LOG_ERR("Could not send error");
+	return -1;
+}
+
+static int32_t
+rte_telemetry_command_port_stats(struct telemetry_impl *telemetry, int action,
+	json_t *data)
+{
+	int ret;
+
+	if (telemetry == NULL) {
+		TELEMETRY_LOG_ERR("Invalid telemetry argument");
+		return -1;
+	}
+
+	if (!json_is_null(data)) {
+		TELEMETRY_LOG_WARN("Data should be NULL JSON object for 'port_stats' command");
+		goto einval_fail;
+	}
+
+	if (action != ACTION_GET) {
+		TELEMETRY_LOG_WARN("Invalid action for this command");
+		goto einval_fail;
+	}
+
+	return 0;
+
+einval_fail:
+	ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+	if (ret < 0)
+		TELEMETRY_LOG_ERR("Could not send error");
+	return -1;
+}
+
+static int32_t
+rte_telemetry_stat_names_to_ids(struct telemetry_impl *telemetry,
+	const char * const *stat_names, uint32_t *stat_ids,
+	uint64_t num_stat_names)
+{
+	struct rte_metric_name *names;
+	int ret, num_metrics;
+	uint32_t i, k;
+
+	if (stat_names == NULL) {
+		TELEMETRY_LOG_WARN("Invalid stat_names argument");
+		goto einval_fail;
+	}
+
+	if (num_stat_names <= 0) {
+		TELEMETRY_LOG_WARN("Invalid num_stat_names argument");
+		goto einval_fail;
+	}
+
+	num_metrics = rte_metrics_get_names(NULL, 0);
+	if (num_metrics < 0) {
+		TELEMETRY_LOG_ERR("Cannot get metrics count");
+		goto eperm_fail;
+	} else if (num_metrics == 0) {
+		TELEMETRY_LOG_WARN("No metrics have been registered");
+		goto eperm_fail;
+	}
+
+	names = malloc(sizeof(struct rte_metric_name) * num_metrics);
+	if (names == NULL) {
+		TELEMETRY_LOG_ERR("Cannot allocate memory for names");
+
+		ret = rte_telemetry_send_error_response(telemetry, -ENOMEM);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Could not send error");
+
+		return -1;
+	}
+
+	ret = rte_metrics_get_names(names, num_metrics);
+	if (ret < 0 || ret > num_metrics) {
+		TELEMETRY_LOG_ERR("Cannot get metrics names");
+		free(names);
+		goto eperm_fail;
+	}
+
+	k = 0;
+	for (i = 0; i < (uint32_t)num_stat_names; i++) {
+		uint32_t j;
+		for (j = 0; j < (uint32_t)num_metrics; j++) {
+			if (strcmp(stat_names[i], names[j].name) == 0) {
+				stat_ids[k] = j;
+				k++;
+				break;
+			}
+		}
+	}
+
+	if (k != num_stat_names) {
+		TELEMETRY_LOG_WARN("Invalid stat names provided");
+		free(names);
+		goto einval_fail;
+	}
+
+	free(names);
+	return 0;
+
+einval_fail:
+	ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+	if (ret < 0)
+		TELEMETRY_LOG_ERR("Could not send error");
+	return -1;
+
+eperm_fail:
+	ret = rte_telemetry_send_error_response(telemetry, -EPERM);
+	if (ret < 0)
+		TELEMETRY_LOG_ERR("Could not send error");
+	return -1;
+}
+
+int32_t
+rte_telemetry_command_ports_all_stat_values(struct telemetry_impl *telemetry,
+	 int action, json_t *data)
+{
+	int ret, num_metrics, i, p;
+	struct rte_metric_name *names;
+	uint64_t num_port_ids = 0;
+
+	if (telemetry == NULL) {
+		TELEMETRY_LOG_ERR("Invalid telemetry argument");
+		return -1;
+	}
+
+	if (action != ACTION_GET) {
+		TELEMETRY_LOG_WARN("Invalid action for this command");
+		ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Could not send error");
+		return -1;
+	}
+
+	if (json_is_object(data)) {
+		TELEMETRY_LOG_WARN("Invalid data provided for this command");
+		ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Could not send error");
+		return -1;
+	}
+
+	num_metrics = rte_metrics_get_names(NULL, 0);
+	if (num_metrics < 0) {
+		TELEMETRY_LOG_ERR("Cannot get metrics count");
+
+		ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Could not send error");
+
+		return -1;
+	} else if (num_metrics == 0) {
+		TELEMETRY_LOG_ERR("No metrics to display (none have been registered)");
+
+		ret = rte_telemetry_send_error_response(telemetry, -EPERM);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Could not send error");
+
+		return -1;
+	}
+
+	names = malloc(sizeof(struct rte_metric_name) * num_metrics);
+	if (names == NULL) {
+		TELEMETRY_LOG_ERR("Cannot allocate memory");
+		ret = rte_telemetry_send_error_response(telemetry,
+			 -ENOMEM);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Could not send error");
+		return -1;
+	}
+
+	const char *stat_names[num_metrics];
+	uint32_t stat_ids[num_metrics];
+
+	RTE_ETH_FOREACH_DEV(p) {
+		num_port_ids++;
+	}
+
+	if (!num_port_ids) {
+		TELEMETRY_LOG_WARN("No active ports");
+
+		ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Could not send error");
+
+		goto fail;
+	}
+
+	ret = rte_metrics_get_names(names, num_metrics);
+	for (i = 0; i < num_metrics; i++)
+		stat_names[i] = names[i].name;
+
+	ret = rte_telemetry_stat_names_to_ids(telemetry, stat_names, stat_ids,
+		num_metrics);
+	if (ret < 0) {
+		TELEMETRY_LOG_ERR("Could not convert stat names to IDs");
+		goto fail;
+	}
+
+	return 0;
+
+fail:
+	free(names);
+	return -1;
+}
+
+int32_t
+rte_telemetry_command_ports_stats_values_by_name(struct telemetry_impl
+	*telemetry, int action, json_t *data)
+{
+	int ret;
+	json_t *port_ids_json = json_object_get(data, "ports");
+	json_t *stat_names_json = json_object_get(data, "stats");
+	uint64_t num_port_ids = json_array_size(port_ids_json);
+	uint64_t num_stat_names = json_array_size(stat_names_json);
+	const char *stat_names[num_stat_names];
+	uint32_t port_ids[num_port_ids], stat_ids[num_stat_names];
+	size_t index;
+	json_t *value;
+
+	if (telemetry == NULL) {
+		TELEMETRY_LOG_ERR("Invalid telemetry argument");
+		return -1;
+	}
+
+	if (action != ACTION_GET) {
+		TELEMETRY_LOG_WARN("Invalid action for this command");
+		ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Could not send error");
+		return -1;
+	}
+
+	if (!json_is_object(data)) {
+		TELEMETRY_LOG_WARN("Invalid data provided for this command");
+		ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Could not send error");
+		return -1;
+	}
+
+	if (!json_is_array(port_ids_json) ||
+		 !json_is_array(stat_names_json)) {
+		TELEMETRY_LOG_WARN("Invalid input data array(s)");
+		ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Could not send error");
+		return -1;
+	}
+
+	json_array_foreach(port_ids_json, index, value) {
+		if (!json_is_integer(value)) {
+			TELEMETRY_LOG_WARN("Port ID given is not valid");
+			ret = rte_telemetry_send_error_response(telemetry,
+				-EINVAL);
+			if (ret < 0)
+				TELEMETRY_LOG_ERR("Could not send error");
+			return -1;
+		}
+		port_ids[index] = json_integer_value(value);
+		ret = rte_telemetry_is_port_active(port_ids[index]);
+		if (ret < 1) {
+			ret = rte_telemetry_send_error_response(telemetry,
+				-EINVAL);
+			if (ret < 0)
+				TELEMETRY_LOG_ERR("Could not send error");
+			return -1;
+		}
+	}
+
+	json_array_foreach(stat_names_json, index, value) {
+		if (!json_is_string(value)) {
+			TELEMETRY_LOG_WARN("Stat Name given is not a string");
+
+			ret = rte_telemetry_send_error_response(telemetry,
+					-EINVAL);
+			if (ret < 0)
+				TELEMETRY_LOG_ERR("Could not send error");
+
+			return -1;
+		}
+		stat_names[index] = json_string_value(value);
+	}
+
+	ret = rte_telemetry_stat_names_to_ids(telemetry, stat_names, stat_ids,
+		num_stat_names);
+	if (ret < 0) {
+		TELEMETRY_LOG_ERR("Could not convert stat names to IDs");
+		return -1;
+	}
+	return 0;
+}
+
+static int32_t
+rte_telemetry_parse_command(struct telemetry_impl *telemetry, int action,
+	const char *command, json_t *data)
+{
+	int ret;
+	uint32_t i;
+
+	if (telemetry == NULL) {
+		TELEMETRY_LOG_ERR("Invalid telemetry argument");
+		return -1;
+	}
+
+	struct rte_telemetry_command commands[] = {
+		{
+			.text = "clients",
+			.fn = &rte_telemetry_command_clients
+		},
+		{
+			.text = "ports",
+			.fn = &rte_telemetry_command_ports
+		},
+		{
+			.text = "ports_details",
+			.fn = &rte_telemetry_command_ports_details
+		},
+		{
+			.text = "port_stats",
+			.fn = &rte_telemetry_command_port_stats
+		},
+		{
+			.text = "ports_stats_values_by_name",
+			.fn = &rte_telemetry_command_ports_stats_values_by_name
+		},
+		{
+			.text = "ports_all_stat_values",
+			.fn = &rte_telemetry_command_ports_all_stat_values
+		}
+	};
+
+	const uint32_t num_commands = RTE_DIM(commands);
+
+	for (i = 0; i < num_commands; i++) {
+		if (strcmp(command, commands[i].text) == 0) {
+			ret = commands[i].fn(telemetry, action, data);
+			if (ret < 0) {
+				TELEMETRY_LOG_ERR("Command Function for %s failed",
+					commands[i].text);
+				return -1;
+			}
+			return 0;
+		}
+	}
+
+	TELEMETRY_LOG_WARN("\"%s\" command not found", command);
+
+	ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+	if (ret < 0)
+		TELEMETRY_LOG_ERR("Could not send error");
+
+	return -1;
+}
+
+int32_t
+rte_telemetry_parse(struct telemetry_impl *telemetry, char *socket_rx_data)
+{
+	int ret, action_int;
+	json_error_t error;
+	json_t *root, *action, *command, *data;
+
+	if (telemetry == NULL) {
+		TELEMETRY_LOG_ERR("Invalid telemetry argument");
+		return -1;
+	}
+
+	root = json_loads(socket_rx_data, 0, &error);
+	if (root == NULL) {
+		TELEMETRY_LOG_WARN("Could not load JSON object from data passed in : %s",
+				error.text);
+		ret = rte_telemetry_send_error_response(telemetry, -EPERM);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Could not send error");
+		return -EPERM;
+	} else if (!json_is_object(root)) {
+		TELEMETRY_LOG_WARN("JSON Request is not a JSON object");
+		json_decref(root);
+		goto einval_fail;
+	}
+
+	action = json_object_get(root, "action");
+	if (action == NULL) {
+		TELEMETRY_LOG_WARN("Request does not have action field");
+		goto einval_fail;
+	} else if (!json_is_integer(action)) {
+		TELEMETRY_LOG_WARN("Action value is not an integer");
+		goto einval_fail;
+	}
+
+	command = json_object_get(root, "command");
+	if (command == NULL) {
+		TELEMETRY_LOG_WARN("Request does not have command field");
+		goto einval_fail;
+	} else if (!json_is_string(command)) {
+		TELEMETRY_LOG_WARN("Command value is not a string");
+		goto einval_fail;
+	}
+
+	action_int = json_integer_value(action);
+	if (action_int != ACTION_GET && action_int != ACTION_DELETE) {
+		TELEMETRY_LOG_WARN("Invalid action code");
+		goto einval_fail;
+	}
+
+	const char *command_string = json_string_value(command);
+	data = json_object_get(root, "data");
+	if (data == NULL) {
+		TELEMETRY_LOG_WARN("Request does not have data field");
+		goto einval_fail;
+	}
+
+	ret = rte_telemetry_parse_command(telemetry, action_int, command_string,
+		data);
+	if (ret < 0) {
+		TELEMETRY_LOG_WARN("Could not parse command");
+		return -EINVAL;
+	}
+
+	return 0;
+
+einval_fail:
+	ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+	if (ret < 0) {
+		TELEMETRY_LOG_ERR("Could not send error");
+		return -EPERM;
+	}
+	return -EINVAL;
+}
diff --git a/lib/librte_telemetry/rte_telemetry_parser.h b/lib/librte_telemetry/rte_telemetry_parser.h
new file mode 100644
index 0000000..63e633d
--- /dev/null
+++ b/lib/librte_telemetry/rte_telemetry_parser.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include "rte_telemetry_internal.h"
+
+#ifndef _RTE_TELEMETRY_PARSER_H_
+#define _RTE_TELEMETRY_PARSER_H_
+
+int32_t
+rte_telemetry_parse(struct telemetry_impl *telemetry, char *socket_rx_data);
+
+#endif
