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 b725aee..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 { @@ -96,6 +97,7 @@ 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; @@ -344,6 +346,39 @@ 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) +{ + u8 found = 0; + struct gtp5g_dev *gtp; + + + GTP5G_TRC(NULL, "gtp5g_statistic_read"); + + list_for_each_entry_rcu(gtp, &proc_gtp5g_dev, proc_list) { + if (strcmp(get_dev_name(), netdev_name(gtp->dev)) == 0) { + found = 1; + break; + } + } + if (!found) { + GTP5G_ERR(NULL, "Given dev: %s not exists\n", get_dev_name()); + return -1; + } + + 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)); + + 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 0; +} + static ssize_t proc_pdr_write(struct file *filp, const char __user *buffer, size_t len, loff_t *dptr) { @@ -628,6 +663,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 +801,23 @@ 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_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, + .llseek = seq_lseek, + .release = single_release, +}; +#endif + int create_proc(void) { proc_gtp5g = proc_mkdir("gtp5g", NULL); @@ -817,8 +874,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 +904,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);