From fa7cf9c9c5565bd85da48d696614d273abb09185 Mon Sep 17 00:00:00 2001
From: Mohd Husaam Mehdi <husaam.mehdi@iopsys.eu>
Date: Sun, 23 Mar 2025 22:39:15 +0530
Subject: [PATCH] qosmngr: transform from dm_plugin to unified daemon for bbfdm

---
 Makefile                      | 11 +++----
 bbf_plugin/Makefile           | 26 -----------------
 bbf_plugin/qos_bbf_vendor.c   | 48 ------------------------------
 bbf_plugin/qos_bbf_vendor.h   | 20 -------------
 include/qosmngr.h             |  2 ++
 src/main.c                    | 29 ++++++++++++++++--
 {bbf_plugin => src}/qos_bbf.c | 55 +++++++++++++++++++++++++++++++----
 {bbf_plugin => src}/qos_bbf.h |  0
 src/qosmngr.c                 | 25 +++++++++-------
 9 files changed, 97 insertions(+), 119 deletions(-)
 delete mode 100644 bbf_plugin/Makefile
 delete mode 100644 bbf_plugin/qos_bbf_vendor.c
 delete mode 100644 bbf_plugin/qos_bbf_vendor.h
 rename {bbf_plugin => src}/qos_bbf.c (97%)
 rename {bbf_plugin => src}/qos_bbf.h (100%)

diff --git a/Makefile b/Makefile
index d6e8359..c0bd9b3 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ include common.mk
 -include Makefile.diag.inc
 
 QOSMNGR_LIB=libqosmngr.so
-PLUGIN = bbf_plugin
+PLUGIN_DIR = bbf_plugin
 
 GCOV=gcov
 SRC_DIR = src
@@ -12,10 +12,10 @@ SRC_DIR = src
 CODECOVERAGE_SRC = $(addprefix $(SRC_DIR)/, qosmngr.c )
 PROG = $(PROJECT_TOPLEVEL)/qosmngr
 SHARED_LIB = $(PROJECT_TOPLEVEL)/libqosmngr.so
-OBJS = $(addprefix $(SRC_DIR)/, main.o qosmngr.o )
+OBJS = $(addprefix $(SRC_DIR)/, main.o qosmngr.o qos_bbf.o)
 
 PROG_CFLAGS = $(CFLAGS) -I$(INCLUDE_DIR) $(DIAG_CFLAGS) -Werror -fstrict-aliasing
-PROG_LDFLAGS = $(LDFLAGS)
+PROG_LDFLAGS = $(LDFLAGS) -lbbfdm-ubus -lbbfdm-api
 PROG_LIBS = $(COMMON_LDFLAGS) -lgcov
 
 # MUSL has the following issue in snprintf, so it is ignored:
@@ -23,10 +23,7 @@ PROG_CFLAGS += -Wno-format-nonliteral
 
 .PHONY: all clean
 
-all: version $(PLUGIN) $(PROG)
-
-$(PLUGIN): $(OBJS)
-	$(MAKE) -C ./bbf_plugin
+all: version $(PROG)
 
 $(PROG): $(INCLUDE_DIR)/version.h $(OBJS)
 	$(CC) $(PROG_LDFLAGS) -o $@ $^ $(PROG_LIBS)
diff --git a/bbf_plugin/Makefile b/bbf_plugin/Makefile
deleted file mode 100644
index e170fd1..0000000
--- a/bbf_plugin/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-LIB_QOS_BBF := libqos_bbf.so
-LIB_QOS_BBF_VENDOR := libqos_vendor_bbf.so
-
-OBJS  := qos_bbf.o
-OBJS_VENDOR  := qos_bbf_vendor.o
-
-LIB_CFLAGS = $(CFLAGS) -Wall -Werror
-LIB_LDFLAGS = $(LDFLAGS)
-FPIC := -fPIC
-
-.PHONY: all
-
-%.o: %.c
-	$(CC) $(LIB_CFLAGS) $(FPIC) -c -o $@ $<
-
-all: $(LIB_QOS_BBF) $(LIB_QOS_BBF_VENDOR)
-
-$(LIB_QOS_BBF): $(OBJS)
-	$(CC) $(LIB_CFLAGS) $(LIB_LDFLAGS) -shared -o $@ $^
-
-$(LIB_QOS_BBF_VENDOR): $(OBJS_VENDOR)
-	$(CC) $(LIB_CFLAGS) $(LIB_LDFLAGS) -shared -o $@ $^
-
-clean:
-	rm -f *.o $(LIB_QOS_BBF) $(LIB_QOS_BBF_VENDOR)
-
diff --git a/bbf_plugin/qos_bbf_vendor.c b/bbf_plugin/qos_bbf_vendor.c
deleted file mode 100644
index 07c41e1..0000000
--- a/bbf_plugin/qos_bbf_vendor.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2024 iopsys Software Solutions AB
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- *	Author: Rohit Topno <r.topno@gxgroup.eu>
- */
-
-#include "qos_bbf_vendor.h"
-
-/*************************************************************
- * GET & SET PARAM
-*************************************************************/
-static int get_QoSClassification_VLANIDMark(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
-{
-	*value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "vid_mark", "-1");
-	return 0;
-}
-
-static int set_QoSClassification_VLANIDMark(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
-{
-	switch (action)	{
-	case VALUECHECK:
-		if (bbfdm_validate_int(ctx, value, RANGE_ARGS{{"-1",NULL}}, 1))
-			return FAULT_9007;
-		break;
-	case VALUESET:
-		dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "vid_mark", value);
-		break;
-	}
-	return 0;
-}
-
-/* ********** DynamicObj ********** */
-DM_MAP_OBJ tDynamicObj[] = {
-/* parentobj, nextobject, parameter */
-{"Device.QoS.Classification.{i}.", NULL, tQoSClassificationParams},
-{0}
-};
-
-/* *** Device.QoS.Classification.{i}. *** */
-DMLEAF tQoSClassificationParams[] = {
-/* PARAM, permission, type, getvalue, setvalue, bbfdm_type */
-{BBF_VENDOR_PREFIX"VLANIDMark", &DMWRITE, DMT_UNINT, get_QoSClassification_VLANIDMark, set_QoSClassification_VLANIDMark, BBFDM_BOTH},
-{0}
-};
diff --git a/bbf_plugin/qos_bbf_vendor.h b/bbf_plugin/qos_bbf_vendor.h
deleted file mode 100644
index b5eecf4..0000000
--- a/bbf_plugin/qos_bbf_vendor.h
+++ /dev/null
@@ -1,20 +0,0 @@
-
-/*
- * Copyright (C) 2024 iopsys Software Solutions AB
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- *	Author: Rohit Topno <r.topno@gxgroup.eu>
- *
- */
-
-#ifndef __IOPSYS_QOS_H
-#define __IOPSYS_QOS_H
-
-#include "libbbfdm-api/dmcommon.h"
-
-extern DMLEAF tQoSClassificationParams[];
-
-#endif //__IOPSYS_QOS_H
diff --git a/include/qosmngr.h b/include/qosmngr.h
index d745993..59dec71 100644
--- a/include/qosmngr.h
+++ b/include/qosmngr.h
@@ -67,4 +67,6 @@ int qosmngr_get_stats(struct ubus_context *ctx, struct ubus_object *obj,
 		       struct ubus_request_data *req, const char *method,
 		       struct blob_attr *msg);
 
+int prepare_stats_blob(struct blob_buf *b, struct qos_stats *stats, void *dd,
+				char *ifname, int qid);
 #endif /* QOSMNGR_H */
diff --git a/src/main.c b/src/main.c
index 68ffc63..36c3f92 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2,7 +2,7 @@
 /*
  * main.c - qosmngr's boilerplate and entry point
  *
- * Copyright (C) 2020 iopsys Software Solutions AB. All rights reserved.
+ * Copyright (C) 2020-2025 iopsys Software Solutions AB. All rights reserved.
  *
  * Author: Oskar Viljasaar <oskar.viljasaar@iopsys.eu>
  *
@@ -25,13 +25,19 @@
 #include <stdlib.h>
 
 #include <libubus.h>
+#include <libbbfdm-ubus/bbfdm-ubus.h>
 
 #include "qosmngr.h"
 #include "version.h"
 
+#include "qos_bbf.h"
+#include "qos_bbf_vendor.h"
+
 const char *ubus_socket;
 
 struct ubus_context *ctx = NULL;
+extern DM_MAP_OBJ tDynamicObj[];
+static struct bbfdm_context bbfdm_ctx = {0};
 
 const struct blobmsg_policy get_status_policy[NUM_QOS_POLICY] = {
       [QOS_POLICY_IFNAME] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING },
@@ -90,12 +96,19 @@ int main(int argc, char **argv)
 	int ret;
 	int ch;
 	int num_of_q = QOS_MIN_Q_NUM_PER_PORT;
+        int log_level = 6; // default LOG_INFO
+
 
 	/* Logging to syslog */
 	openlog("qosmngr", LOG_PID|LOG_CONS, LOG_LOCAL1);
 
-	while ((ch = getopt(argc, argv, "vsq:e:")) != -1) {
+	while ((ch = getopt(argc, argv, "lvsq:e:")) != -1) {
 		switch (ch) {
+		case 'l':
+			log_level = (int)strtoul(optarg, NULL, 10);
+			if (log_level < 0 || log_level > 7)
+				log_level = 6;
+			break;
 		case 'v':
 			qosmngr_version();
 			exit(0);
@@ -127,10 +140,20 @@ int main(int argc, char **argv)
 	if (ret)
 		goto out;
 
+        memset(&bbfdm_ctx, 0, sizeof(struct bbfdm_context));
+        bbfdm_ubus_set_service_name(&bbfdm_ctx, "qosmngr");
+        bbfdm_ubus_set_log_level(log_level);
+        bbfdm_ubus_load_data_model(tDynamicObj);
+
+	if (bbfdm_ubus_regiter_init(&bbfdm_ctx)) {
+		syslog(LOG_ERR, "Failed to register ubus");
+		goto out;
+	}
+
 	/* Main loop of qosmngr */
 	uloop_run();
-
  out:
+	bbfdm_ubus_regiter_free(&bbfdm_ctx);;
 	ubus_free(ctx);
 	uloop_done();
 
diff --git a/bbf_plugin/qos_bbf.c b/src/qos_bbf.c
similarity index 97%
rename from bbf_plugin/qos_bbf.c
rename to src/qos_bbf.c
index 4b4ca12..11ab70c 100644
--- a/bbf_plugin/qos_bbf.c
+++ b/src/qos_bbf.c
@@ -11,6 +11,8 @@
 
 #include "qos_bbf.h"
 #include "libbbfdm_api.h"
+#include "qosmngr.h"
+
 #define PROTOCOLS_FILE "/etc/protocols"
 
 /*************************************************************
@@ -73,7 +75,7 @@ static unsigned long qos_get_new_order(void)
 
 	uci_foreach_sections("qos", "classify", s) {
 		dmuci_get_value_by_section_string(s, "order", &order);
-		unsigned long order_tol = DM_STRTOL(order);
+		unsigned long order_tol = DM_STRTOUL(order);
 		if (order_tol > max)
 			max = order_tol;
 	}
@@ -99,11 +101,11 @@ static void qos_update_order(const char *order, bool is_del)
 {
 	struct uci_section *classify_s = NULL;
 	char *curr_order = NULL;
-	unsigned long order_tol = DM_STRTOL(order);
+	unsigned long order_tol = DM_STRTOUL(order);
 
 	uci_foreach_sections("qos", "classify", classify_s) {
 		dmuci_get_value_by_section_string(classify_s, "order", &curr_order);
-		unsigned long curr_order_tol = DM_STRTOL(curr_order);
+		unsigned long curr_order_tol = DM_STRTOUL(curr_order);
 		if (curr_order_tol >= order_tol) {
 			char new_order[16] = {0};
 
@@ -1347,6 +1349,26 @@ static int set_QoSClassification_Policer(char *refparam, struct dmctx *ctx, void
 	return 0;
 }
 
+static int get_QoSClassification_VLANIDMark(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+	*value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "vid_mark", "-1");
+	return 0;
+}
+
+static int set_QoSClassification_VLANIDMark(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+	switch (action)	{
+	case VALUECHECK:
+		if (bbfdm_validate_int(ctx, value, RANGE_ARGS{{"-1",NULL}}, 1))
+			return FAULT_9007;
+		break;
+	case VALUESET:
+		dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "vid_mark", value);
+		break;
+	}
+	return 0;
+}
+
 static int get_QoSPolicer_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
 	*value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "enable", "1");
@@ -1846,15 +1868,37 @@ static int get_QoSQueueStats_value(void *data, char *option, char **value)
 	dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "queue", &queue_link);
 	dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "interface", &intf_link);
 
-	if (queue_link && *queue_link && intf_link && *intf_link) {
-		json_object *res = NULL;
+	if (queue_link && *queue_link && DM_STRLEN(queue_link) > 2 && intf_link && *intf_link) {
 		char queue_id[8] = {0};
 
 		snprintf(queue_id, sizeof(queue_id), "%c", queue_link[2]);
+		int qid = (int) DM_STRTOL(queue_id);
+	        struct qos_stats stats = {0};
+
+		if (!prepare_stats_blob(NULL, &stats, NULL, intf_link, qid)) {
+			char val_buf[65] = {0};
+
+			if (!DM_STRNCMP(option, "tx_packets", DM_STRLEN("tx_packets"))) {
+				snprintf(val_buf, sizeof(val_buf), "%lu", stats.tx_packets);
+				*value = dmstrdup(val_buf);
+			} else if (!DM_STRNCMP(option, "tx_bytes", DM_STRLEN("tx_bytes"))) {
+				snprintf(val_buf, sizeof(val_buf), "%lu", stats.tx_bytes);
+				*value = dmstrdup(val_buf);
+			} else if (!DM_STRNCMP(option, "tx_dropped_packets", DM_STRLEN("tx_dropped_packets"))) {
+				snprintf(val_buf, sizeof(val_buf), "%lu", stats.tx_dropped_packets);
+				*value = dmstrdup(val_buf);
+			} else if (!DM_STRNCMP(option, "tx_dropped_bytes", DM_STRLEN("tx_dropped_bytes"))) {
+				snprintf(val_buf, sizeof(val_buf), "%lu", stats.tx_dropped_bytes);
+				*value = dmstrdup(val_buf);
+			}
+		}
+		/*
+		json_object *res = NULL;
 		dmubus_call("qos", "queue_stats", UBUS_ARGS{{"ifname", intf_link, String}, {"qid", queue_id, Integer}}, 2, &res);
 		DM_ASSERT(res, *value = "0");
 		json_object *queue_obj = dmjson_select_obj_in_array_idx(res, 0, 1, "queues");
 		*value = dmjson_get_value(queue_obj, 1, option);
+		*/
 	}
 	return 0;
 }
@@ -2108,6 +2152,7 @@ DMLEAF tQoSClassificationParams[] = {
 {"TrafficClass", &DMWRITE, DMT_INT, get_QoSClassification_TrafficClass, set_QoSClassification_TrafficClass, BBFDM_BOTH},
 {"Policer", &DMWRITE, DMT_STRING, get_QoSClassification_Policer, set_QoSClassification_Policer, BBFDM_BOTH},
 //{"App", &DMWRITE, DMT_STRING, get_QoSClassification_App, set_QoSClassification_App, BBFDM_BOTH},
+{BBF_VENDOR_PREFIX"VLANIDMark", &DMWRITE, DMT_UNINT, get_QoSClassification_VLANIDMark, set_QoSClassification_VLANIDMark, BBFDM_BOTH},
 {0}
 };
 
diff --git a/bbf_plugin/qos_bbf.h b/src/qos_bbf.h
similarity index 100%
rename from bbf_plugin/qos_bbf.h
rename to src/qos_bbf.h
diff --git a/src/qosmngr.c b/src/qosmngr.c
index 4c05a3f..9f50116 100644
--- a/src/qosmngr.c
+++ b/src/qosmngr.c
@@ -313,9 +313,9 @@ free_and_return:
  *  @param dd output parameter pointer to void used for blob buffer array elements
  *  @param ifname input parameter pointer to char for which to get stats
  *  @param qid input parameter integer queue identifier for which to get stats
- *  retrun integer value 0 on success and -1 on failure
+ *  return integer value 0 on success and -1 on failure
  */
-static int prepare_stats_blob(struct blob_buf *b, struct qos_stats *stats, void *dd,
+int prepare_stats_blob(struct blob_buf *b, struct qos_stats *stats, void *dd,
 				char *ifname, int qid)
 {
 	int index;
@@ -358,19 +358,24 @@ static int prepare_stats_blob(struct blob_buf *b, struct qos_stats *stats, void
 		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;
+
+		// update the contents so the caller gets latest data
+		memcpy(stats, q_stat, sizeof(struct qos_stats));
 	}
 
-	dd = blobmsg_open_table(b, "");
+	if (b) {
+		dd = blobmsg_open_table(b, "");
 
-	blobmsg_add_string(b, "iface", ifname);
-	blobmsg_add_u32(b, "qid", (uint32_t)qid);
-        blobmsg_add_u64(b, "tx_packets", (uint64_t)q_stat->tx_packets);
-        blobmsg_add_u64(b, "tx_bytes", (uint64_t)q_stat->tx_bytes);
-        blobmsg_add_u64(b, "tx_dropped_packets", (uint64_t)q_stat->tx_dropped_packets);
-        blobmsg_add_u64(b, "tx_dropped_bytes", (uint64_t)q_stat->tx_dropped_bytes);
+		blobmsg_add_string(b, "iface", ifname);
+		blobmsg_add_u32(b, "qid", (uint32_t)qid);
+	        blobmsg_add_u64(b, "tx_packets", (uint64_t)q_stat->tx_packets);
+	        blobmsg_add_u64(b, "tx_bytes", (uint64_t)q_stat->tx_bytes);
+        	blobmsg_add_u64(b, "tx_dropped_packets", (uint64_t)q_stat->tx_dropped_packets);
+	        blobmsg_add_u64(b, "tx_dropped_bytes", (uint64_t)q_stat->tx_dropped_bytes);
 
 
-	blobmsg_close_table(b, dd);
+		blobmsg_close_table(b, dd);
+	}
 
 	return ret;
 }
-- 
GitLab