705 lines
18 KiB
Diff
705 lines
18 KiB
Diff
|
|
From ffe630818e3d5118ac0163e75e2f1ec774d3e4c9 Mon Sep 17 00:00:00 2001
|
||
|
|
From: JofDiamonds <kwb0523@163.com>
|
||
|
|
Date: Mon, 8 May 2023 10:04:42 +0800
|
||
|
|
Subject: [PATCH] add proc file interface
|
||
|
|
|
||
|
|
---
|
||
|
|
bwmcli.h | 6 +-
|
||
|
|
ko/Makefile | 16 ++
|
||
|
|
ko/bwm.c | 567 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
ko/bwm.h | 69 +++++++
|
||
|
|
4 files changed, 657 insertions(+), 1 deletion(-)
|
||
|
|
create mode 100644 ko/Makefile
|
||
|
|
create mode 100644 ko/bwm.c
|
||
|
|
create mode 100644 ko/bwm.h
|
||
|
|
|
||
|
|
diff --git a/bwmcli.h b/bwmcli.h
|
||
|
|
index f7d4c62..a319130 100644
|
||
|
|
--- a/bwmcli.h
|
||
|
|
+++ b/bwmcli.h
|
||
|
|
@@ -60,6 +60,10 @@ struct TcCmd {
|
||
|
|
|
||
|
|
#define BWM_LOG_DEBUG(fmt, args...) syslog(LOG_DEBUG, "[BWM_DEBUG]: " fmt, ## args)
|
||
|
|
#define BWM_LOG_ERR(fmt, args...) syslog(LOG_ERR, "[BWM]: " fmt, ## args)
|
||
|
|
-#define BWM_LOG_INFO(fmt, args...) ((void)printf(fmt, ## args))
|
||
|
|
+#define BWM_LOG_INFO(fmt, args...) \
|
||
|
|
+ do { \
|
||
|
|
+ (void)printf(fmt, ## args); \
|
||
|
|
+ syslog(LOG_INFO, "[BWM]: " fmt, ## args); \
|
||
|
|
+ } while (0)
|
||
|
|
|
||
|
|
#endif /* __BWMCLI_H__ */
|
||
|
|
diff --git a/ko/Makefile b/ko/Makefile
|
||
|
|
new file mode 100644
|
||
|
|
index 0000000..7eae5f5
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/ko/Makefile
|
||
|
|
@@ -0,0 +1,16 @@
|
||
|
|
+CONFIG_MODULE_SIG=n
|
||
|
|
+
|
||
|
|
+obj-m := bwm.o
|
||
|
|
+
|
||
|
|
+KERNELDIR ?= /lib/modules/$(shell uname -r)/build
|
||
|
|
+PWD := $(shell pwd)
|
||
|
|
+
|
||
|
|
+LINUX_VER ?= $(shell ls /usr/src/ | grep linux)
|
||
|
|
+USERSRC ?= /usr/src/$(LINUX_VER)
|
||
|
|
+EXTRA_CFLAGS = -I$(USERSRC)
|
||
|
|
+
|
||
|
|
+all:
|
||
|
|
+ $(MAKE) -C $(KERNELDIR) M=$(PWD)
|
||
|
|
+clean:
|
||
|
|
+ @rm -rf *.o *.mod *.mod.c *.mod.o *.ko *.order *.symvers .*.cmd
|
||
|
|
+
|
||
|
|
diff --git a/ko/bwm.c b/ko/bwm.c
|
||
|
|
new file mode 100644
|
||
|
|
index 0000000..6be6cbe
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/ko/bwm.c
|
||
|
|
@@ -0,0 +1,567 @@
|
||
|
|
+/*
|
||
|
|
+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2022. All rights reserved.
|
||
|
|
+ * Description: Network bandwidth management tool
|
||
|
|
+ */
|
||
|
|
+#include "bwm.h"
|
||
|
|
+
|
||
|
|
+static char *envp[] = { "HOME=/", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
|
||
|
|
+
|
||
|
|
+static ssize_t proc_value_get(const char __user *buffer, unsigned long count, char *value)
|
||
|
|
+{
|
||
|
|
+ if (count == 0 || count >= MAX_BUF_SIZE) {
|
||
|
|
+ return -EINVAL;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ if (copy_from_user(value, buffer, count)) {
|
||
|
|
+ return -EINVAL;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ value[count - 1] = '\0';
|
||
|
|
+
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static int proc_net_qos_enable_open(struct seq_file *seq, void *offset)
|
||
|
|
+{
|
||
|
|
+ seq_printf(seq, "%s\n", net_qos_enable);
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static int proc_net_qos_enable_single_open(struct inode *inode, struct file *file)
|
||
|
|
+{
|
||
|
|
+ return single_open(file, proc_net_qos_enable_open, NULL);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static int qos_cmd_upcall(char *cmd)
|
||
|
|
+{
|
||
|
|
+ int ret = 0;
|
||
|
|
+ char *argv[] = {
|
||
|
|
+ "/bin/bash",
|
||
|
|
+ "-c",
|
||
|
|
+ cmd,
|
||
|
|
+ NULL,
|
||
|
|
+ };
|
||
|
|
+
|
||
|
|
+ ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
|
||
|
|
+ if (ret) {
|
||
|
|
+ BWM_LOG_ERR("call_usermodehelper failed, ret = %d", ret);
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return ret;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static ssize_t proc_net_qos_enable_write(struct file *file, const char __user *buffer,
|
||
|
|
+ unsigned long count, loff_t *ppos)
|
||
|
|
+{
|
||
|
|
+ int ret = 0;
|
||
|
|
+ char nspid[MAX_BUF_SIZE] = { 0 };
|
||
|
|
+ char cmd[MAX_CMD_LEN] = { 0 };
|
||
|
|
+
|
||
|
|
+ ret = proc_value_get(buffer, count, nspid);
|
||
|
|
+ if (ret != 0) {
|
||
|
|
+ BWM_LOG_ERR("proc_value_get failed");
|
||
|
|
+ return count;
|
||
|
|
+ }
|
||
|
|
+ BWM_LOG_DEBUG("get nspid %s", nspid);
|
||
|
|
+
|
||
|
|
+ ret = snprintf(cmd, MAX_CMD_LEN, "%s -n -t %s %s -e", NSENTER_PATH, nspid, BWMCLI_PATH);
|
||
|
|
+ if (ret < 0) {
|
||
|
|
+ BWM_LOG_ERR("failed to snprintf enable qos cmd");
|
||
|
|
+ return ret;
|
||
|
|
+ }
|
||
|
|
+ BWM_LOG_DEBUG("enable qos cmd:%s", cmd);
|
||
|
|
+
|
||
|
|
+ ret = qos_cmd_upcall(cmd);
|
||
|
|
+ if (ret != 0) {
|
||
|
|
+ BWM_LOG_ERR("qos_enable_upcall failed");
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return count;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static int proc_net_qos_disable_open(struct seq_file *seq, void *offset)
|
||
|
|
+{
|
||
|
|
+ seq_printf(seq, "%s\n", net_qos_disable);
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static int proc_net_qos_disable_single_open(struct inode *inode, struct file *file)
|
||
|
|
+{
|
||
|
|
+ return single_open(file, proc_net_qos_disable_open, NULL);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static ssize_t proc_net_qos_disable_write(struct file *file, const char __user *buffer,
|
||
|
|
+ unsigned long count, loff_t *ppos)
|
||
|
|
+{
|
||
|
|
+ int ret = 0;
|
||
|
|
+ char nspid[MAX_BUF_SIZE] = { 0 };
|
||
|
|
+ char cmd[MAX_CMD_LEN] = { 0 };
|
||
|
|
+
|
||
|
|
+ ret = proc_value_get(buffer, count, nspid);
|
||
|
|
+ if (ret != 0) {
|
||
|
|
+ BWM_LOG_ERR("proc_value_get failed");
|
||
|
|
+ return count;
|
||
|
|
+ }
|
||
|
|
+ BWM_LOG_DEBUG("get nspid %s.", nspid);
|
||
|
|
+
|
||
|
|
+ ret = snprintf(cmd, MAX_CMD_LEN, "%s -n -t %s %s -d", NSENTER_PATH, nspid, BWMCLI_PATH);
|
||
|
|
+ if (ret < 0) {
|
||
|
|
+ BWM_LOG_ERR("failed to snprintf disable qos cmd");
|
||
|
|
+ return ret;
|
||
|
|
+ }
|
||
|
|
+ BWM_LOG_DEBUG("disable qos cmd:%s", cmd);
|
||
|
|
+
|
||
|
|
+ ret = qos_cmd_upcall(cmd);
|
||
|
|
+ if (ret != 0) {
|
||
|
|
+ BWM_LOG_ERR("disable qos failed");
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return count;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static int proc_net_qos_bandwidth_open(struct seq_file *seq, void *offset)
|
||
|
|
+{
|
||
|
|
+ seq_printf(seq, "%s\n", net_qos_bandwidth);
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static int proc_net_qos_bandwidth_single_open(struct inode *inode, struct file *file)
|
||
|
|
+{
|
||
|
|
+ return single_open(file, proc_net_qos_bandwidth_open, NULL);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static ssize_t proc_net_qos_bandwidth_write(struct file *file, const char __user *buffer,
|
||
|
|
+ unsigned long count, loff_t *ppos)
|
||
|
|
+{
|
||
|
|
+ int ret = 0;
|
||
|
|
+ char bandwidth[MAX_BUF_SIZE] = { 0 };
|
||
|
|
+ char cmd[MAX_CMD_LEN] = { 0 };
|
||
|
|
+
|
||
|
|
+ ret = proc_value_get(buffer, count, bandwidth);
|
||
|
|
+ if (ret != 0) {
|
||
|
|
+ BWM_LOG_ERR("proc_value_get failed");
|
||
|
|
+ return count;
|
||
|
|
+ }
|
||
|
|
+ BWM_LOG_DEBUG("change net_qos_bandwidth to %s.", bandwidth);
|
||
|
|
+
|
||
|
|
+ ret = snprintf(cmd, MAX_CMD_LEN, "%s -s bandwidth %s", BWMCLI_PATH, bandwidth);
|
||
|
|
+ if (ret < 0) {
|
||
|
|
+ BWM_LOG_ERR("failed to snprintf bandwidth cmd");
|
||
|
|
+ return ret;
|
||
|
|
+ }
|
||
|
|
+ BWM_LOG_DEBUG("set bandwidth cmd : %s", cmd);
|
||
|
|
+
|
||
|
|
+ ret = qos_cmd_upcall(cmd);
|
||
|
|
+ if (ret != 0) {
|
||
|
|
+ BWM_LOG_ERR("set bandwidth failed");
|
||
|
|
+ return ret;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ ret = snprintf(net_qos_bandwidth, MAX_BUF_SIZE, "%s", bandwidth);
|
||
|
|
+ if (ret < 0) {
|
||
|
|
+ BWM_LOG_ERR("failed to write net_qos_bandwidth");
|
||
|
|
+ return ret;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return count;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static int proc_net_qos_waterline_open(struct seq_file *seq, void *offset)
|
||
|
|
+{
|
||
|
|
+ seq_printf(seq, "%s\n", net_qos_waterline);
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static int proc_net_qos_waterline_single_open(struct inode *inode, struct file *file)
|
||
|
|
+{
|
||
|
|
+ return single_open(file, proc_net_qos_waterline_open, NULL);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static ssize_t proc_net_qos_waterline_write(struct file *file, const char __user *buffer,
|
||
|
|
+ unsigned long count, loff_t *ppos)
|
||
|
|
+{
|
||
|
|
+ int ret = 0;
|
||
|
|
+ char waterline[MAX_BUF_SIZE] = { 0 };
|
||
|
|
+ char cmd[MAX_CMD_LEN] = { 0 };
|
||
|
|
+
|
||
|
|
+ ret = proc_value_get(buffer, count, waterline);
|
||
|
|
+ if (ret != 0) {
|
||
|
|
+ BWM_LOG_ERR("proc_value_get failed");
|
||
|
|
+ return count;
|
||
|
|
+ }
|
||
|
|
+ BWM_LOG_DEBUG("change net_qos_waterline to %s.", waterline);
|
||
|
|
+
|
||
|
|
+ ret = snprintf(cmd, MAX_CMD_LEN, "%s -s waterline %s", BWMCLI_PATH, waterline);
|
||
|
|
+ if (ret < 0) {
|
||
|
|
+ BWM_LOG_ERR("failed to snprintf waterline cmd");
|
||
|
|
+ return ret;
|
||
|
|
+ }
|
||
|
|
+ BWM_LOG_DEBUG("set waterline cmd : %s", cmd);
|
||
|
|
+
|
||
|
|
+ ret = qos_cmd_upcall(cmd);
|
||
|
|
+ if (ret != 0) {
|
||
|
|
+ BWM_LOG_ERR("set waterline failed");
|
||
|
|
+ return ret;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ ret = snprintf(net_qos_waterline, MAX_BUF_SIZE, "%s", waterline);
|
||
|
|
+ if (ret < 0) {
|
||
|
|
+ BWM_LOG_ERR("failed to write net_qos_waterline");
|
||
|
|
+ return ret;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return count;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static int proc_net_qos_devs_open(struct seq_file *seq, void *offset)
|
||
|
|
+{
|
||
|
|
+ seq_printf(seq, "%s\n", net_qos_devs);
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static int proc_net_qos_devs_single_open(struct inode *inode, struct file *file)
|
||
|
|
+{
|
||
|
|
+ return single_open(file, proc_net_qos_devs_open, NULL);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static ssize_t proc_net_qos_devs_write(struct file *file, const char __user *buffer,
|
||
|
|
+ unsigned long count, loff_t *ppos)
|
||
|
|
+{
|
||
|
|
+ int ret = 0;
|
||
|
|
+ char nspid[MAX_BUF_SIZE] = { 0 };
|
||
|
|
+ char cmd[MAX_CMD_LEN] = { 0 };
|
||
|
|
+
|
||
|
|
+ ret = proc_value_get(buffer, count, nspid);
|
||
|
|
+ if (ret != 0) {
|
||
|
|
+ BWM_LOG_ERR("proc_value_get failed");
|
||
|
|
+ return count;
|
||
|
|
+ }
|
||
|
|
+ BWM_LOG_DEBUG("write nspid:%s to net_qos_devs", nspid);
|
||
|
|
+
|
||
|
|
+ ret = snprintf(cmd, MAX_CMD_LEN, "%s -n -t %s %s -p devs > /proc/qos/net_qos_devstatus",
|
||
|
|
+ NSENTER_PATH, nspid, BWMCLI_PATH);
|
||
|
|
+ if (ret < 0) {
|
||
|
|
+ BWM_LOG_ERR("failed to snprintf devs status cmd");
|
||
|
|
+ return ret;
|
||
|
|
+ }
|
||
|
|
+ BWM_LOG_DEBUG("get devs status cmd:%s", cmd);
|
||
|
|
+
|
||
|
|
+ ret = qos_cmd_upcall(cmd);
|
||
|
|
+ if (ret != 0) {
|
||
|
|
+ BWM_LOG_ERR("write net_qos_devs failed");
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return count;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static int proc_net_qos_devstatus_open(struct seq_file *seq, void *offset)
|
||
|
|
+{
|
||
|
|
+ seq_printf(seq, "%s\n", net_qos_devstatus);
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static int proc_net_qos_devstatus_single_open(struct inode *inode, struct file *file)
|
||
|
|
+{
|
||
|
|
+ return single_open(file, proc_net_qos_devstatus_open, NULL);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static ssize_t proc_net_qos_devstatus_write(struct file *file, const char __user *buffer,
|
||
|
|
+ unsigned long count, loff_t *ppos)
|
||
|
|
+{
|
||
|
|
+ int ret = 0;
|
||
|
|
+ char data[MAX_BUF_SIZE] = { 0 };
|
||
|
|
+
|
||
|
|
+ ret = proc_value_get(buffer, count, data);
|
||
|
|
+ if (ret != 0) {
|
||
|
|
+ BWM_LOG_ERR("proc_value_get failed");
|
||
|
|
+ return count;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ ret = snprintf(net_qos_devstatus, MAX_DATA_SIZE, "%s", data);
|
||
|
|
+ if (ret < 0) {
|
||
|
|
+ BWM_LOG_ERR("write net_qos_devstatus failed");
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return count;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static atomic_t stats_flag = ATOMIC_INIT(0);
|
||
|
|
+
|
||
|
|
+static int proc_net_qos_stats_open(struct seq_file *seq, void *offset)
|
||
|
|
+{
|
||
|
|
+ seq_printf(seq, "%s\n", net_qos_stats);
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static int proc_net_qos_stats_single_open(struct inode *inode, struct file *file)
|
||
|
|
+{
|
||
|
|
+ int ret = 0;
|
||
|
|
+ char cmd[MAX_CMD_LEN] = { 0 };
|
||
|
|
+
|
||
|
|
+ if (atomic_read(&stats_flag) == 0) {
|
||
|
|
+ ret = snprintf(cmd, MAX_CMD_LEN, "%s -p stats > /proc/qos/net_qos_stats", BWMCLI_PATH);
|
||
|
|
+ if (ret < 0) {
|
||
|
|
+ BWM_LOG_ERR("failed to snprintf stats cmd");
|
||
|
|
+ return ret;
|
||
|
|
+ }
|
||
|
|
+ BWM_LOG_DEBUG("stats cmd:%s", cmd);
|
||
|
|
+
|
||
|
|
+ atomic_xchg(&stats_flag, 1);
|
||
|
|
+ ret = qos_cmd_upcall(cmd);
|
||
|
|
+ if (ret != 0) {
|
||
|
|
+ BWM_LOG_ERR("read net_qos_stats failed");
|
||
|
|
+ atomic_xchg(&stats_flag, 0);
|
||
|
|
+ return ret;
|
||
|
|
+ }
|
||
|
|
+ single_open(file, proc_net_qos_stats_open, NULL);
|
||
|
|
+ return 0;
|
||
|
|
+ }
|
||
|
|
+ atomic_xchg(&stats_flag, 0);
|
||
|
|
+ return single_open(file, proc_net_qos_stats_open, NULL);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static ssize_t proc_net_qos_stats_write(struct file *file, const char __user *buffer,
|
||
|
|
+ unsigned long count, loff_t *ppos)
|
||
|
|
+{
|
||
|
|
+ int ret = 0;
|
||
|
|
+ char stats[MAX_BUF_SIZE] = { 0 };
|
||
|
|
+
|
||
|
|
+ ret = proc_value_get(buffer, count, stats);
|
||
|
|
+ if (ret != 0) {
|
||
|
|
+ BWM_LOG_ERR("proc_value_get failed");
|
||
|
|
+ return count;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ ret = snprintf(net_qos_stats, MAX_DATA_SIZE, "%s", stats);
|
||
|
|
+ if (ret < 0) {
|
||
|
|
+ BWM_LOG_ERR("write net_qos_stats failed");
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return count;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static int proc_net_qos_version_open(struct seq_file *seq, void *offset)
|
||
|
|
+{
|
||
|
|
+ seq_printf(seq, "version:%s\n", net_qos_version);
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static int proc_net_qos_version_single_open(struct inode *inode, struct file *file)
|
||
|
|
+{
|
||
|
|
+ return single_open(file, proc_net_qos_version_open, NULL);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static int proc_net_qos_debug_open(struct seq_file *seq, void *offset)
|
||
|
|
+{
|
||
|
|
+ seq_printf(seq, "%u\n", net_qos_debug);
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static int proc_net_qos_debug_single_open(struct inode *inode, struct file *file)
|
||
|
|
+{
|
||
|
|
+ return single_open(file, proc_net_qos_debug_open, NULL);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static ssize_t proc_net_qos_debug_write(struct file *file, const char __user *buffer,
|
||
|
|
+ unsigned long count, loff_t *ppos)
|
||
|
|
+{
|
||
|
|
+ int ret = 0;
|
||
|
|
+ char debug_mode[MAX_BUF_SIZE] = { 0 };
|
||
|
|
+ unsigned int net_qos_debug_new = net_qos_debug;
|
||
|
|
+
|
||
|
|
+ ret = proc_value_get(buffer, count, debug_mode);
|
||
|
|
+ if (ret != 0) {
|
||
|
|
+ BWM_LOG_ERR("proc_value_get failed");
|
||
|
|
+ return count;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ net_qos_debug_new = simple_strtoul(debug_mode, NULL, 0);
|
||
|
|
+ if (net_qos_debug_new != 0 && net_qos_debug_new != 1) {
|
||
|
|
+ BWM_LOG_ERR("invalid input of debug mode(%d), valid input: 0 or 1.", net_qos_debug_new);
|
||
|
|
+ return count;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ BWM_LOG_INFO("change debug mode, old is %u, new is %u.", net_qos_debug, net_qos_debug_new);
|
||
|
|
+ net_qos_debug = net_qos_debug_new;
|
||
|
|
+
|
||
|
|
+ return count;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static struct proc_ops bwm_proc_net_qos_enable_ops = {
|
||
|
|
+ .proc_open = proc_net_qos_enable_single_open,
|
||
|
|
+ .proc_write = proc_net_qos_enable_write,
|
||
|
|
+ .proc_read = seq_read,
|
||
|
|
+ .proc_release = single_release,
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+static struct proc_ops bwm_proc_net_qos_disable_ops = {
|
||
|
|
+ .proc_open = proc_net_qos_disable_single_open,
|
||
|
|
+ .proc_write = proc_net_qos_disable_write,
|
||
|
|
+ .proc_read = seq_read,
|
||
|
|
+ .proc_release = single_release,
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+static struct proc_ops bwm_proc_net_qos_bandwidth_ops = {
|
||
|
|
+ .proc_open = proc_net_qos_bandwidth_single_open,
|
||
|
|
+ .proc_write = proc_net_qos_bandwidth_write,
|
||
|
|
+ .proc_read = seq_read,
|
||
|
|
+ .proc_release = single_release,
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+static struct proc_ops bwm_proc_net_qos_waterline_ops = {
|
||
|
|
+ .proc_open = proc_net_qos_waterline_single_open,
|
||
|
|
+ .proc_write = proc_net_qos_waterline_write,
|
||
|
|
+ .proc_read = seq_read,
|
||
|
|
+ .proc_release = single_release,
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+static struct proc_ops bwm_proc_net_qos_devs_ops = {
|
||
|
|
+ .proc_open = proc_net_qos_devs_single_open,
|
||
|
|
+ .proc_write = proc_net_qos_devs_write,
|
||
|
|
+ .proc_read = seq_read,
|
||
|
|
+ .proc_release = single_release,
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+static struct proc_ops bwm_proc_net_qos_devstatus_ops = {
|
||
|
|
+ .proc_open = proc_net_qos_devstatus_single_open,
|
||
|
|
+ .proc_write = proc_net_qos_devstatus_write,
|
||
|
|
+ .proc_read = seq_read,
|
||
|
|
+ .proc_release = single_release,
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+static struct proc_ops bwm_proc_net_qos_stats_ops = {
|
||
|
|
+ .proc_open = proc_net_qos_stats_single_open,
|
||
|
|
+ .proc_write = proc_net_qos_stats_write,
|
||
|
|
+ .proc_read = seq_read,
|
||
|
|
+ .proc_release = single_release,
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+static struct proc_ops bwm_proc_net_qos_version_ops = {
|
||
|
|
+ .proc_open = proc_net_qos_version_single_open,
|
||
|
|
+ .proc_read = seq_read,
|
||
|
|
+ .proc_release = single_release,
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+static struct proc_ops bwm_proc_net_qos_debug_ops = {
|
||
|
|
+ .proc_open = proc_net_qos_debug_single_open,
|
||
|
|
+ .proc_write = proc_net_qos_debug_write,
|
||
|
|
+ .proc_read = seq_read,
|
||
|
|
+ .proc_release = single_release,
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+static struct bwm_proc g_proc_table[] = {
|
||
|
|
+ {
|
||
|
|
+ .proc_name = "net_qos_enable",
|
||
|
|
+ .entry = NULL,
|
||
|
|
+ .ops = &bwm_proc_net_qos_enable_ops,
|
||
|
|
+ },
|
||
|
|
+ {
|
||
|
|
+ .proc_name = "net_qos_disable",
|
||
|
|
+ .entry = NULL,
|
||
|
|
+ .ops = &bwm_proc_net_qos_disable_ops,
|
||
|
|
+ },
|
||
|
|
+ {
|
||
|
|
+ .proc_name = "net_qos_bandwidth",
|
||
|
|
+ .entry = NULL,
|
||
|
|
+ .ops = &bwm_proc_net_qos_bandwidth_ops,
|
||
|
|
+ },
|
||
|
|
+ {
|
||
|
|
+ .proc_name = "net_qos_waterline",
|
||
|
|
+ .entry = NULL,
|
||
|
|
+ .ops = &bwm_proc_net_qos_waterline_ops,
|
||
|
|
+ },
|
||
|
|
+ {
|
||
|
|
+ .proc_name = "net_qos_devs",
|
||
|
|
+ .entry = NULL,
|
||
|
|
+ .ops = &bwm_proc_net_qos_devs_ops,
|
||
|
|
+ },
|
||
|
|
+ {
|
||
|
|
+ .proc_name = "net_qos_devstatus",
|
||
|
|
+ .entry = NULL,
|
||
|
|
+ .ops = &bwm_proc_net_qos_devstatus_ops,
|
||
|
|
+ },
|
||
|
|
+ {
|
||
|
|
+ .proc_name = "net_qos_stats",
|
||
|
|
+ .entry = NULL,
|
||
|
|
+ .ops = &bwm_proc_net_qos_stats_ops,
|
||
|
|
+ },
|
||
|
|
+ {
|
||
|
|
+ .proc_name = "net_qos_version",
|
||
|
|
+ .entry = NULL,
|
||
|
|
+ .ops = &bwm_proc_net_qos_version_ops,
|
||
|
|
+ },
|
||
|
|
+ {
|
||
|
|
+ .proc_name = "net_qos_debug",
|
||
|
|
+ .entry = NULL,
|
||
|
|
+ .ops = &bwm_proc_net_qos_debug_ops,
|
||
|
|
+ },
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+static int bwm_proc_init(void)
|
||
|
|
+{
|
||
|
|
+ unsigned int i;
|
||
|
|
+ int ret = 0;
|
||
|
|
+
|
||
|
|
+ bwm_proc_root_dir = proc_mkdir(BWM_PROC_ROOTDIR, NULL);
|
||
|
|
+ if (!bwm_proc_root_dir) {
|
||
|
|
+ BWM_LOG_ERR("can't create /proc/%s.", BWM_PROC_ROOTDIR);
|
||
|
|
+ return -EFAULT;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ for (i = 0; i < sizeof(g_proc_table) / sizeof(struct bwm_proc); i++) {
|
||
|
|
+ g_proc_table[i].entry = proc_create_seq_data(g_proc_table[i].proc_name, BWM_CTL_PROC_PERM,
|
||
|
|
+ bwm_proc_root_dir, NULL, NULL);
|
||
|
|
+ if (!g_proc_table[i].entry) {
|
||
|
|
+ BWM_LOG_ERR("can't create file(%s).", g_proc_table[i].proc_name);
|
||
|
|
+ ret = -EFAULT;
|
||
|
|
+ break;
|
||
|
|
+ }
|
||
|
|
+ g_proc_table[i].entry->proc_ops = g_proc_table[i].ops;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ if (ret != 0) {
|
||
|
|
+ BWM_LOG_ERR("bwm_proc_init failed");
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return ret;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static void bwm_proc_clean(void)
|
||
|
|
+{
|
||
|
|
+ unsigned int i;
|
||
|
|
+
|
||
|
|
+ if (bwm_proc_root_dir) {
|
||
|
|
+ for (i = 0; i < sizeof(g_proc_table) / sizeof(struct bwm_proc); i++) {
|
||
|
|
+ if (g_proc_table[i].entry) {
|
||
|
|
+ remove_proc_entry(g_proc_table[i].proc_name, bwm_proc_root_dir);
|
||
|
|
+ g_proc_table[i].entry = NULL;
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+ remove_proc_entry(BWM_PROC_ROOTDIR, NULL);
|
||
|
|
+ bwm_proc_root_dir = NULL;
|
||
|
|
+ }
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static int __init bwm_init(void)
|
||
|
|
+{
|
||
|
|
+ int ret = 0;
|
||
|
|
+
|
||
|
|
+ ret = bwm_proc_init();
|
||
|
|
+ if (ret != 0) {
|
||
|
|
+ bwm_proc_clean();
|
||
|
|
+ return ret;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ BWM_LOG_INFO("bwm loaded");
|
||
|
|
+ return ret;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static void __exit bwm_exit(void)
|
||
|
|
+{
|
||
|
|
+ bwm_proc_clean();
|
||
|
|
+ BWM_LOG_INFO("bwm unloaded");
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+module_init(bwm_init);
|
||
|
|
+module_exit(bwm_exit);
|
||
|
|
+MODULE_LICENSE("GPL");
|
||
|
|
diff --git a/ko/bwm.h b/ko/bwm.h
|
||
|
|
new file mode 100644
|
||
|
|
index 0000000..a977c0e
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/ko/bwm.h
|
||
|
|
@@ -0,0 +1,69 @@
|
||
|
|
+/*
|
||
|
|
+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2022. All rights reserved.
|
||
|
|
+ * Description: Network bandwidth management tool
|
||
|
|
+ */
|
||
|
|
+#ifndef NET_BWM_H
|
||
|
|
+#define NET_BWM_H
|
||
|
|
+
|
||
|
|
+#include <asm/atomic.h>
|
||
|
|
+#include <linux/delay.h>
|
||
|
|
+#include <linux/kernel.h>
|
||
|
|
+#include <linux/module.h>
|
||
|
|
+#include <linux/proc_fs.h>
|
||
|
|
+#include <linux/seq_file.h>
|
||
|
|
+#include <linux/types.h>
|
||
|
|
+#include <fs/proc/internal.h>
|
||
|
|
+
|
||
|
|
+#define BWM_PROC_ROOTDIR "qos"
|
||
|
|
+#define BWM_CTL_PROC_PERM 0644
|
||
|
|
+
|
||
|
|
+#define NSENTER_PATH "/usr/bin/nsenter"
|
||
|
|
+#define BWMCLI_PATH "/usr/bin/bwmcli"
|
||
|
|
+
|
||
|
|
+#define MAX_BUF_SIZE 128
|
||
|
|
+#define MAX_CMD_LEN (256 + NAME_MAX)
|
||
|
|
+#define MAX_DATA_SIZE 1024
|
||
|
|
+
|
||
|
|
+static char net_qos_disable[] = "please write <nspid> to net_qos_disable to disable qos";
|
||
|
|
+static char net_qos_enable[] = "please write <nspid> to net_qos_enable to enable qos";
|
||
|
|
+static char net_qos_bandwidth[MAX_BUF_SIZE];
|
||
|
|
+static char net_qos_waterline[MAX_BUF_SIZE];
|
||
|
|
+static char net_qos_devs[] = "please write <nspid> to net_qos_devs and read dev status from net_qos_devstatus";
|
||
|
|
+static char net_qos_devstatus[MAX_DATA_SIZE];
|
||
|
|
+static char net_qos_stats[MAX_DATA_SIZE];
|
||
|
|
+static char net_qos_version[] = "1.1";
|
||
|
|
+static unsigned int net_qos_debug = 0;
|
||
|
|
+
|
||
|
|
+static struct proc_dir_entry *bwm_proc_root_dir = NULL;
|
||
|
|
+
|
||
|
|
+struct bwm_proc {
|
||
|
|
+ const char *proc_name;
|
||
|
|
+ struct proc_dir_entry *entry;
|
||
|
|
+ struct proc_ops *ops;
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+#define PFX "BWM"
|
||
|
|
+
|
||
|
|
+#define BWM_LOG_INFO(fmt, ...) \
|
||
|
|
+ do { \
|
||
|
|
+ printk(KERN_INFO "[" PFX "] INFO:" fmt "[%s():%u]\n", ##__VA_ARGS__, __FUNCTION__, __LINE__); \
|
||
|
|
+ } while (0)
|
||
|
|
+
|
||
|
|
+#define BWM_LOG_NOTICE(fmt, ...) \
|
||
|
|
+ do { \
|
||
|
|
+ printk(KERN_NOTICE "[" PFX "] NOTICE:" fmt, ##__VA_ARGS__); \
|
||
|
|
+ } while (0)
|
||
|
|
+
|
||
|
|
+#define BWM_LOG_ERR(fmt, ...) \
|
||
|
|
+ do { \
|
||
|
|
+ printk(KERN_ERR "[" PFX "] ERROR:" fmt "[%s():%u]\n", ##__VA_ARGS__, __FUNCTION__, __LINE__); \
|
||
|
|
+ } while (0)
|
||
|
|
+
|
||
|
|
+#define BWM_LOG_DEBUG(fmt, ...) \
|
||
|
|
+ do { \
|
||
|
|
+ if (net_qos_debug == 1) { \
|
||
|
|
+ printk(KERN_DEBUG "[" PFX "] DEBUG:" fmt "[%s():%u]\n", ##__VA_ARGS__, __FUNCTION__, __LINE__); \
|
||
|
|
+ } \
|
||
|
|
+ } while (0)
|
||
|
|
+
|
||
|
|
+#endif
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|