From cb918d1b64a79cb4c5046025b173b4bec575efd8 Mon Sep 17 00:00:00 2001 From: ycchen Date: Thu, 8 Aug 2024 15:45:06 +0800 Subject: [PATCH 1/2] proc statistic data --- src/proc.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/src/proc.c b/src/proc.c index b725aee..3115719 100644 --- a/src/proc.c +++ b/src/proc.c @@ -88,6 +88,19 @@ struct proc_gtp5g_seq bool seq_enable; }; +struct proc_gtp5g_statistic +{ + u64 tx_ul_byte; + u64 tx_dl_byte; + u64 tx_ul_pkt; + u64 tx_dl_pkt; + + u64 rx_ul_byte; + u64 rx_dl_byte; + u64 rx_ul_pkt; + u64 rx_dl_pkt; +}; + struct proc_dir_entry *proc_gtp5g = NULL; struct proc_dir_entry *proc_gtp5g_dbg = NULL; struct proc_dir_entry *proc_gtp5g_pdr = NULL; @@ -96,12 +109,14 @@ struct proc_dir_entry *proc_gtp5g_qer = NULL; struct proc_dir_entry *proc_gtp5g_urr = NULL; struct proc_dir_entry *proc_gtp5g_qos = NULL; struct proc_dir_entry *proc_gtp5g_seq = NULL; +struct proc_dir_entry *proc_gtp5g_statistic = NULL; struct proc_gtp5g_pdr proc_pdr; struct proc_gtp5g_far proc_far; struct proc_gtp5g_qer proc_qer; struct proc_gtp5g_urr proc_urr; struct proc_gtp5g_qos proc_qos; struct proc_gtp5g_seq proc_seq; +struct proc_gtp5g_statistic proc_statistic; u64 proc_seid = 0; u16 proc_pdr_id = 0; @@ -344,6 +359,70 @@ static ssize_t proc_seq_write(struct file *filp, const char __user *buffer, return -1; } +static int gtp5g_statistic_read(struct seq_file *s, void *v) +{ + GTP5G_TRC(NULL, "gtp5g_statistic_read"); + seq_printf(s, "Statistic: \n"); + seq_printf(s, "\t RX UL(bytes) : %llu\n", proc_statistic.rx_ul_byte); + seq_printf(s, "\t TX UL(bytes) : %llu\n", proc_statistic.tx_ul_byte); + seq_printf(s, "\t RX DL(bytes) : %llu\n", proc_statistic.rx_dl_byte); + seq_printf(s, "\t TX DL(bytes) : %llu\n", proc_statistic.tx_dl_byte); + + seq_printf(s, "\t RX UL(packets) : %llu\n", proc_statistic.rx_ul_pkt); + seq_printf(s, "\t TX UL(packets) : %llu\n", proc_statistic.tx_ul_pkt); + seq_printf(s, "\t RX DL(packets) : %llu\n", proc_statistic.rx_dl_pkt); + seq_printf(s, "\t TX DL(packets) : %llu\n", proc_statistic.tx_dl_pkt); + + return 0; +} + +static ssize_t proc_statistic_write(struct file *filp, const char __user *buffer, + size_t len, loff_t *dptr) +{ + char buf[32], dev_name[32]; + u8 found = 0; + unsigned long buf_len = min(len, sizeof(buf)-1); + struct gtp5g_dev *gtp; + + if (copy_from_user(buf, buffer, buf_len)) { + GTP5G_ERR(NULL, "Failed to read buffer: %s\n", buffer); + goto err; + } + + buf[buf_len] = 0; + if (sscanf(buf, "%s", dev_name) != 1) { + GTP5G_ERR(NULL, "device name is not valid: %s\n", buf); + goto err; + } + + + list_for_each_entry_rcu(gtp, &proc_gtp5g_dev, proc_list) { + if (strcmp(dev_name, netdev_name(gtp->dev)) == 0) { + found = 1; + break; + } + } + if (!found) { + GTP5G_ERR(NULL, "Given dev: %s not exists\n", dev_name); + goto err; + } + + memset(&proc_statistic, 0, sizeof(proc_statistic)); + proc_statistic.rx_ul_byte = (u64)atomic_read(>p->rx.ul_byte); + proc_statistic.tx_ul_byte = (u64)atomic_read(>p->tx.ul_byte); + proc_statistic.rx_dl_byte = (u64)atomic_read(>p->rx.dl_byte); + proc_statistic.tx_dl_byte = (u64)atomic_read(>p->tx.dl_byte); + + proc_statistic.rx_ul_pkt = (u64)atomic_read(>p->rx.ul_pkt); + proc_statistic.tx_ul_pkt = (u64)atomic_read(>p->tx.ul_pkt); + proc_statistic.rx_dl_pkt = (u64)atomic_read(>p->rx.dl_pkt); + proc_statistic.tx_dl_pkt = (u64)atomic_read(>p->tx.dl_pkt); + + return strnlen(buf, buf_len); +err: + return -1; +} + static ssize_t proc_pdr_write(struct file *filp, const char __user *buffer, size_t len, loff_t *dptr) { @@ -628,6 +707,11 @@ static int proc_seq_read(struct inode *inode, struct file *file) return single_open(file, gtp5g_seq_read, NULL); } +static int proc_statistic_read(struct inode *inode, struct file *file) +{ + return single_open(file, gtp5g_statistic_read, NULL); +} + #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0) static const struct proc_ops proc_gtp5g_dbg_ops = { .proc_open = proc_dbg_read, @@ -761,6 +845,25 @@ static const struct file_operations proc_gtp5g_seq_ops = { }; #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0) +static const struct proc_ops proc_gtp5g_statistic_ops = { + .proc_open = proc_statistic_read, + .proc_read = seq_read, + .proc_write = proc_statistic_write, + .proc_lseek = seq_lseek, + .proc_release = single_release, +}; +#else +static const struct file_operations proc_gtp5g_statistic_ops = { + .owner = THIS_MODULE, + .open = proc_statistic_read, + .read = seq_read, + .write = proc_statistic_write, + .llseek = seq_lseek, + .release = single_release, +}; +#endif + int create_proc(void) { proc_gtp5g = proc_mkdir("gtp5g", NULL); @@ -817,8 +920,17 @@ int create_proc(void) goto remove_qos_proc; } + proc_gtp5g_statistic = proc_create("statistic", (S_IFREG | S_IRUGO | S_IWUGO), + proc_gtp5g, &proc_gtp5g_statistic_ops); + if (!proc_gtp5g_statistic) { + GTP5G_ERR(NULL, "Failed to create /proc/gtp5g/statistic\n"); + goto remove_statistic_proc; + } + return 0; + remove_statistic_proc: + remove_proc_entry("statistic", proc_gtp5g); remove_qos_proc: remove_proc_entry("qos", proc_gtp5g); remove_urr_proc: @@ -838,6 +950,7 @@ int create_proc(void) void remove_proc() { + remove_proc_entry("statistic", proc_gtp5g); remove_proc_entry("qos", proc_gtp5g); remove_proc_entry("seq", proc_gtp5g); remove_proc_entry("urr", proc_gtp5g); From 983afccea995a86ece817272dcf0cbe3634e6f50 Mon Sep 17 00:00:00 2001 From: ycchen Date: Wed, 28 Aug 2024 15:38:10 +0800 Subject: [PATCH 2/2] update reading statistic data --- include/dev.h | 3 ++ src/gtpu/dev.c | 12 ++++++++ src/gtpu/link.c | 4 +++ src/proc.c | 80 +++++++++++-------------------------------------- 4 files changed, 36 insertions(+), 63 deletions(-) diff --git a/include/dev.h b/include/dev.h index 7f8f15a..b6f6724 100644 --- a/include/dev.h +++ b/include/dev.h @@ -49,4 +49,7 @@ extern struct gtp5g_dev *gtp5g_find_dev(struct net *, int, int); extern int dev_hashtable_new(struct gtp5g_dev *, int); extern void gtp5g_hashtable_free(struct gtp5g_dev *); +extern char *get_dev_name(void); +extern void set_dev_name(char *); + #endif // __GTP5G_DEV_H__ diff --git a/src/gtpu/dev.c b/src/gtpu/dev.c index e4a913d..87ff5d8 100644 --- a/src/gtpu/dev.c +++ b/src/gtpu/dev.c @@ -13,6 +13,18 @@ #include "pktinfo.h" #include "log.h" +char *device_name = NULL; + +char *get_dev_name() +{ + return device_name; +} + +void set_dev_name(char *val) +{ + device_name = val; +} + struct gtp5g_dev *gtp5g_find_dev(struct net *src_net, int ifindex, int netnsfd) { struct gtp5g_dev *gtp = NULL; diff --git a/src/gtpu/link.c b/src/gtpu/link.c index c45ab02..b0a8c26 100644 --- a/src/gtpu/link.c +++ b/src/gtpu/link.c @@ -66,6 +66,10 @@ static int gtp5g_newlink(struct net *src_net, struct net_device *dev, u32 fd1; int hashsize, err; + if (dev != NULL && dev->name != NULL) { + set_dev_name(dev->name); + } + gtp = netdev_priv(dev); if (!data[IFLA_GTP5G_FD1]) { diff --git a/src/proc.c b/src/proc.c index 3115719..fece235 100644 --- a/src/proc.c +++ b/src/proc.c @@ -9,6 +9,7 @@ #include "far.h" #include "util.h" +#include "dev.h" struct list_head proc_gtp5g_dev; struct proc_gtp5g_pdr { @@ -88,19 +89,6 @@ struct proc_gtp5g_seq bool seq_enable; }; -struct proc_gtp5g_statistic -{ - u64 tx_ul_byte; - u64 tx_dl_byte; - u64 tx_ul_pkt; - u64 tx_dl_pkt; - - u64 rx_ul_byte; - u64 rx_dl_byte; - u64 rx_ul_pkt; - u64 rx_dl_pkt; -}; - struct proc_dir_entry *proc_gtp5g = NULL; struct proc_dir_entry *proc_gtp5g_dbg = NULL; struct proc_dir_entry *proc_gtp5g_pdr = NULL; @@ -116,7 +104,6 @@ struct proc_gtp5g_qer proc_qer; struct proc_gtp5g_urr proc_urr; struct proc_gtp5g_qos proc_qos; struct proc_gtp5g_seq proc_seq; -struct proc_gtp5g_statistic proc_statistic; u64 proc_seid = 0; u16 proc_pdr_id = 0; @@ -361,66 +348,35 @@ static ssize_t proc_seq_write(struct file *filp, const char __user *buffer, static int gtp5g_statistic_read(struct seq_file *s, void *v) { - GTP5G_TRC(NULL, "gtp5g_statistic_read"); - seq_printf(s, "Statistic: \n"); - seq_printf(s, "\t RX UL(bytes) : %llu\n", proc_statistic.rx_ul_byte); - seq_printf(s, "\t TX UL(bytes) : %llu\n", proc_statistic.tx_ul_byte); - seq_printf(s, "\t RX DL(bytes) : %llu\n", proc_statistic.rx_dl_byte); - seq_printf(s, "\t TX DL(bytes) : %llu\n", proc_statistic.tx_dl_byte); - - seq_printf(s, "\t RX UL(packets) : %llu\n", proc_statistic.rx_ul_pkt); - seq_printf(s, "\t TX UL(packets) : %llu\n", proc_statistic.tx_ul_pkt); - seq_printf(s, "\t RX DL(packets) : %llu\n", proc_statistic.rx_dl_pkt); - seq_printf(s, "\t TX DL(packets) : %llu\n", proc_statistic.tx_dl_pkt); - - return 0; -} - -static ssize_t proc_statistic_write(struct file *filp, const char __user *buffer, - size_t len, loff_t *dptr) -{ - char buf[32], dev_name[32]; u8 found = 0; - unsigned long buf_len = min(len, sizeof(buf)-1); struct gtp5g_dev *gtp; - if (copy_from_user(buf, buffer, buf_len)) { - GTP5G_ERR(NULL, "Failed to read buffer: %s\n", buffer); - goto err; - } - - buf[buf_len] = 0; - if (sscanf(buf, "%s", dev_name) != 1) { - GTP5G_ERR(NULL, "device name is not valid: %s\n", buf); - goto err; - } - - + + GTP5G_TRC(NULL, "gtp5g_statistic_read"); + list_for_each_entry_rcu(gtp, &proc_gtp5g_dev, proc_list) { - if (strcmp(dev_name, netdev_name(gtp->dev)) == 0) { + if (strcmp(get_dev_name(), netdev_name(gtp->dev)) == 0) { found = 1; break; } } if (!found) { - GTP5G_ERR(NULL, "Given dev: %s not exists\n", dev_name); - goto err; + GTP5G_ERR(NULL, "Given dev: %s not exists\n", get_dev_name()); + return -1; } - memset(&proc_statistic, 0, sizeof(proc_statistic)); - proc_statistic.rx_ul_byte = (u64)atomic_read(>p->rx.ul_byte); - proc_statistic.tx_ul_byte = (u64)atomic_read(>p->tx.ul_byte); - proc_statistic.rx_dl_byte = (u64)atomic_read(>p->rx.dl_byte); - proc_statistic.tx_dl_byte = (u64)atomic_read(>p->tx.dl_byte); + seq_printf(s, "Statistic: \n"); + seq_printf(s, "\t RX UL(bytes) : %llu\n", (u64)atomic_read(>p->rx.ul_byte)); + seq_printf(s, "\t TX UL(bytes) : %llu\n", (u64)atomic_read(>p->tx.ul_byte)); + seq_printf(s, "\t RX DL(bytes) : %llu\n", (u64)atomic_read(>p->rx.dl_byte)); + seq_printf(s, "\t TX DL(bytes) : %llu\n", (u64)atomic_read(>p->tx.dl_byte)); - proc_statistic.rx_ul_pkt = (u64)atomic_read(>p->rx.ul_pkt); - proc_statistic.tx_ul_pkt = (u64)atomic_read(>p->tx.ul_pkt); - proc_statistic.rx_dl_pkt = (u64)atomic_read(>p->rx.dl_pkt); - proc_statistic.tx_dl_pkt = (u64)atomic_read(>p->tx.dl_pkt); + seq_printf(s, "\t RX UL(packets) : %llu\n", (u64)atomic_read(>p->rx.ul_pkt)); + seq_printf(s, "\t TX UL(packets) : %llu\n", (u64)atomic_read(>p->tx.ul_pkt)); + seq_printf(s, "\t RX DL(packets) : %llu\n", (u64)atomic_read(>p->rx.dl_pkt)); + seq_printf(s, "\t TX DL(packets) : %llu\n", (u64)atomic_read(>p->tx.dl_pkt)); - return strnlen(buf, buf_len); -err: - return -1; + return 0; } static ssize_t proc_pdr_write(struct file *filp, const char __user *buffer, @@ -849,7 +805,6 @@ static const struct file_operations proc_gtp5g_seq_ops = { static const struct proc_ops proc_gtp5g_statistic_ops = { .proc_open = proc_statistic_read, .proc_read = seq_read, - .proc_write = proc_statistic_write, .proc_lseek = seq_lseek, .proc_release = single_release, }; @@ -858,7 +813,6 @@ static const struct file_operations proc_gtp5g_statistic_ops = { .owner = THIS_MODULE, .open = proc_statistic_read, .read = seq_read, - .write = proc_statistic_write, .llseek = seq_lseek, .release = single_release, };