Skip to content
Snippets Groups Projects
Commit 060964ea authored by Maxim Menshikov's avatar Maxim Menshikov
Browse files

qosmngr: make queue number assignment independent on interface name

parent e3d608e4
No related branches found
No related tags found
1 merge request!12qosmngr: make queue number assignment independent on interface name
......@@ -33,10 +33,6 @@
/* Used as an internal value to query all the queues */
#define QOS_QUEUE_ANY -1
/* Used for getting interface indexes for global q_stat array */
#define MIN_INDEX 48
#define MAX_INDEX 57
/* Used for fetching keys from ubus json reqest */
#define SEPERATOR 44
#define QUOTE 34
......@@ -45,8 +41,20 @@
#define PARAM1 "ifname"
#define PARAM2 "qid"
/** Container for single interface data (with multiple queues) */
typedef struct qos_interface_data {
char if_name[IFNAMSIZ]; /**< Cached interface name */
size_t q_count; /**< Cached number of queues */
struct qos_stats *q_stat; /**< Cached queue statistics */
} qos_interface_data;
static int init_flag = 1;
static struct qos_stats **q_stat = {0};
/** Number of interfaces currently cached by qosmngr */
static size_t interface_count = 0;
/** Array of interfaces cached by qosmngr */
static qos_interface_data *interfaces = NULL;
/**
* get_no_queues function for getting number of queues on device by calling uci qos config
......@@ -93,11 +101,22 @@ done:
*/
static int get_interface_index(const char *ifname)
{
int i;
size_t i;
size_t len = strlen(ifname);
for (i = 0; i < interface_count; ++i) {
qos_interface_data *cur = &interfaces[i];
if (strncmp(cur->if_name, ifname, len) == 0) {
size_t cur_len = strlen(cur->if_name);
for (i = 0; i < strlen(ifname); i++) {
if ((ifname[i] >= MIN_INDEX) && (ifname[i] <= MAX_INDEX)) {
return atoi(ifname + i);
if (cur_len != len) {
if (sscanf(ifname + len, ".%*d") != 1) {
continue;
}
}
return (int)i;
}
}
......@@ -105,84 +124,69 @@ static int get_interface_index(const char *ifname)
}
/**
* get_no_ports function for getting number of ports on device by calling uci port config
* init_qstat function for initializing global q_stat structure for sustainable stats
* @param none
* retrun integer value 0 on success and -1 on failure
*/
static int get_no_ports()
static int init_qstat()
{
int ports = 0;
int ret = 0;
int index = 0;
syslog(LOG_ERR, "Initializing global stat structure.\n");
struct uci_package *uci_pkg = NULL;
struct uci_element *uci_elmnt = NULL;
struct uci_context *uci_ctx = uci_alloc_context();
interface_count = 0;
uci_load(uci_ctx, "ports", &uci_pkg);
if (!uci_pkg) {
syslog(LOG_ERR, "Failed to load configuration\n");
ports = -1;
ret = -1;
goto done;
}
interface_count = 0;
uci_foreach_element(&uci_pkg->sections, uci_elmnt) {
struct uci_section *uci_sec = uci_to_section(uci_elmnt);
if (uci_sec)
ports++;
interface_count++;
}
done:
uci_unload(uci_ctx, uci_pkg);
uci_free_context(uci_ctx);
return ports;
}
/**
* init_qstat function for initializing global q_stat structure for sustainable stats
* @param none
* retrun integer value 0 on success and -1 on failure
*/
static int init_qstat()
{
int ret = 0;
int index = 0;
syslog(LOG_ERR, "Initializing global stat structure.\n");
int ports = get_no_ports();
q_stat = (struct qos_stats **)calloc(ports, sizeof(struct qos_stats *));
if (q_stat == NULL) {
interfaces = (qos_interface_data *)calloc(interface_count,
sizeof(qos_interface_data));
if (interfaces == NULL) {
syslog(LOG_ERR, "Initialization failed during memory allocation.\n");
ret = -1;
return ret;
}
struct uci_package *uci_pkg = NULL;
struct uci_element *uci_elmnt = NULL;
struct uci_context *uci_ctx = uci_alloc_context();
uci_load(uci_ctx, "ports", &uci_pkg);
if (!uci_pkg) {
syslog(LOG_ERR, "Failed to load configuration\n");
ret = -1;
goto done;
goto done_unload;
}
uci_foreach_element(&uci_pkg->sections, uci_elmnt) {
struct uci_section *uci_sec = uci_to_section(uci_elmnt);
if (uci_sec) {
struct uci_option *uci_opn = uci_lookup_option(uci_ctx, uci_sec, "ifname");
index = get_interface_index(uci_opn->v.string);
int queues = get_no_queues(uci_opn->v.string);
q_stat[index] = (struct qos_stats *)calloc(queues, sizeof(struct qos_stats));
if (q_stat[index] == NULL) {
qos_interface_data *data = &interfaces[index];
struct uci_option *uci_opn = uci_lookup_option(uci_ctx, uci_sec, "ifname");
int queues;
queues = get_no_queues(uci_opn->v.string);
strcpy(data->if_name, uci_opn->v.string);
data->q_count = queues;
data->q_stat = (struct qos_stats *)calloc(queues,
sizeof(struct qos_stats));
if (data->q_stat == NULL) {
syslog(LOG_ERR, "Initialization failed during memory allocation.\n");
ret = -1;
uci_unload(uci_ctx, uci_pkg);
goto done;
goto done_unload;
}
index++;
}
}
done_unload:
uci_unload(uci_ctx, uci_pkg);
done:
uci_free_context(uci_ctx);
......@@ -204,6 +208,8 @@ static int prepare_stats_blob(struct blob_buf *b, struct qos_stats *stats, void
int index;
int ret = 0;
int is_read_and_reset;
qos_interface_data *iface;
struct qos_stats *q_stat;
// Initialize global q_stat global struct
if (init_flag) {
......@@ -222,29 +228,43 @@ static int prepare_stats_blob(struct blob_buf *b, struct qos_stats *stats, void
}
index = get_interface_index(ifname);
if (index < 0 || index >= interface_count) {
syslog(LOG_ERR, "Invalid interface index %d (out of %zu)",
index, interface_count);
return -1;
}
iface = &interfaces[index];
if (qid < 0 || qid >= iface->q_count) {
syslog(LOG_ERR, "Invalid queue index %d (out of %zu)",
qid, iface->q_count);
return -1;
}
q_stat = &iface->q_stat[qid];
/*BCM968 CHIP, stats read from driver is accunulated stats, while in other its read and reset */
if (!is_read_and_reset) {
q_stat[index][qid].tx_packets = stats->tx_packets;
q_stat[index][qid].tx_bytes = stats->tx_bytes;
q_stat[index][qid].tx_dropped_packets = stats->tx_dropped_packets;
q_stat[index][qid].tx_dropped_bytes = stats->tx_dropped_bytes;
q_stat->tx_packets = stats->tx_packets;
q_stat->tx_bytes = stats->tx_bytes;
q_stat->tx_dropped_packets = stats->tx_dropped_packets;
q_stat->tx_dropped_bytes = stats->tx_dropped_bytes;
}
else {
q_stat[index][qid].tx_packets += stats->tx_packets;
q_stat[index][qid].tx_bytes += stats->tx_bytes;
q_stat[index][qid].tx_dropped_packets += stats->tx_dropped_packets;
q_stat[index][qid].tx_dropped_bytes += stats->tx_dropped_bytes;
q_stat->tx_packets += stats->tx_packets;
q_stat->tx_bytes += stats->tx_bytes;
q_stat->tx_dropped_packets += stats->tx_dropped_packets;
q_stat->tx_dropped_bytes += stats->tx_dropped_bytes;
}
dd = blobmsg_open_table(b, "");
blobmsg_add_string(b, "iface", ifname);
blobmsg_add_u32(b, "qid", qid);
blobmsg_add_u32(b, "tx_packets", q_stat[index][qid].tx_packets);
blobmsg_add_u32(b, "tx_bytes", q_stat[index][qid].tx_bytes);
blobmsg_add_u32(b, "tx_dropped_packets", q_stat[index][qid].tx_dropped_packets);
blobmsg_add_u32(b, "tx_dropped_bytes", q_stat[index][qid].tx_dropped_bytes);
blobmsg_add_u32(b, "tx_packets", q_stat->tx_packets);
blobmsg_add_u32(b, "tx_bytes", q_stat->tx_bytes);
blobmsg_add_u32(b, "tx_dropped_packets", q_stat->tx_dropped_packets);
blobmsg_add_u32(b, "tx_dropped_bytes", q_stat->tx_dropped_bytes);
blobmsg_close_table(b, dd);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment