procfs: Add support for routing tables.

This commit is contained in:
Gregory Nutt 2017-08-11 14:50:39 -06:00
parent fdca465da6
commit 65698da12d
9 changed files with 300 additions and 122 deletions

5
TODO
View File

@ -2097,6 +2097,11 @@ o Build system
$ make apps_distclean $ make apps_distclean
One solution to this might be to making the special target
.PRECIOUS depend on apps/libapps.a. Then if make receives a
signal, it will not delete apps/libapps.a. This would have to
be done in all Makefiles.
Status Open Status Open
Priority: Medium-High. It is a rare event that control-C happens at just the Priority: Medium-High. It is a rare event that control-C happens at just the
point in time. However, when it does occur the resulting code may point in time. However, when it does occur the resulting code may

View File

@ -63,6 +63,11 @@ config FS_PROCFS_EXCLUDE_NET
depends on NET depends on NET
default n default n
config FS_PROC_EXCLUDE_ROUTE
bool "Exclude routing table"
depends on !FS_PROCFS_EXCLUDE_NET && NET_ROUTE
default n
config FS_PROCFS_EXCLUDE_MTD config FS_PROCFS_EXCLUDE_MTD
bool "Exclude mtd" bool "Exclude mtd"
depends on MTD depends on MTD

View File

@ -87,6 +87,7 @@ extern const struct procfs_operations uptime_operations;
*/ */
extern const struct procfs_operations net_procfsoperations; extern const struct procfs_operations net_procfsoperations;
extern const struct procfs_operations net_procfs_routeoperations;
extern const struct procfs_operations mtd_procfsoperations; extern const struct procfs_operations mtd_procfsoperations;
extern const struct procfs_operations part_procfsoperations; extern const struct procfs_operations part_procfsoperations;
extern const struct procfs_operations smartfs_procfsoperations; extern const struct procfs_operations smartfs_procfsoperations;
@ -112,42 +113,46 @@ static const struct procfs_entry_s g_procfs_entries[] =
#endif #endif
{ {
#ifndef CONFIG_FS_PROCFS_EXCLUDE_PROCESS #ifndef CONFIG_FS_PROCFS_EXCLUDE_PROCESS
{ "[0-9]*/**", &proc_operations }, { "[0-9]*/**", &proc_operations, PROCFS_UNKOWN_TYPE },
{ "[0-9]*", &proc_operations }, { "[0-9]*", &proc_operations, PROCFS_DIR_TYPE },
#endif #endif
#if defined(CONFIG_SCHED_CPULOAD) && !defined(CONFIG_FS_PROCFS_EXCLUDE_CPULOAD) #if defined(CONFIG_SCHED_CPULOAD) && !defined(CONFIG_FS_PROCFS_EXCLUDE_CPULOAD)
{ "cpuload", &cpuload_operations }, { "cpuload", &cpuload_operations, PROCFS_FILE_TYPE },
#endif #endif
#if defined(CONFIG_MM_KERNEL_HEAP) && !defined(CONFIG_FS_PROCFS_EXCLUDE_KMM) #if defined(CONFIG_MM_KERNEL_HEAP) && !defined(CONFIG_FS_PROCFS_EXCLUDE_KMM)
{ "kmm", &kmm_operations }, { "kmm", &kmm_operations, PROCFS_FILE_TYPE },
#endif #endif
#if defined(CONFIG_MODULE) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) #if defined(CONFIG_MODULE) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE)
{ "modules", &module_operations }, { "modules", &module_operations, PROCFS_DIR_TYPE },
#endif #endif
#if defined(CONFIG_FS_SMARTFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_SMARTFS) #if defined(CONFIG_FS_SMARTFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_SMARTFS)
//{ "fs/smartfs", &smartfs_procfsoperations }, //{ "fs/smartfs", &smartfs_procfsoperations, PROCFS_DIR_TYPE },
{ "fs/smartfs**", &smartfs_procfsoperations }, { "fs/smartfs**", &smartfs_procfsoperations, PROCFS_UNKOWN_TYPE },
#endif #endif
#if defined(CONFIG_NET) && !defined(CONFIG_FS_PROCFS_EXCLUDE_NET) #if defined(CONFIG_NET) && !defined(CONFIG_FS_PROCFS_EXCLUDE_NET)
{ "net", &net_procfsoperations }, { "net", &net_procfsoperations, PROCFS_DIR_TYPE },
{ "net/**", &net_procfsoperations }, #if defined(CONFIG_NET_ROUTE) && !defined(CONFIG_FS_PROCFS_EXCLUDE_ROUTE)
{ "net/route", &net_procfs_routeoperations, PROCFS_DIR_TYPE },
{ "net/route/**", &net_procfs_routeoperations, PROCFS_UNKOWN_TYPE },
#endif
{ "net/**", &net_procfsoperations, PROCFS_UNKOWN_TYPE },
#endif #endif
#if defined(CONFIG_MTD) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MTD) #if defined(CONFIG_MTD) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MTD)
{ "mtd", &mtd_procfsoperations }, { "mtd", &mtd_procfsoperations, PROCFS_FILE_TYPE },
#endif #endif
#if defined(CONFIG_MTD_PARTITION) && !defined(CONFIG_FS_PROCFS_EXCLUDE_PARTITIONS) #if defined(CONFIG_MTD_PARTITION) && !defined(CONFIG_FS_PROCFS_EXCLUDE_PARTITIONS)
{ "partitions", &part_procfsoperations }, { "partitions", &part_procfsoperations, PROCFS_DIR_TYPE },
#endif #endif
#if !defined(CONFIG_FS_PROCFS_EXCLUDE_UPTIME) #if !defined(CONFIG_FS_PROCFS_EXCLUDE_UPTIME)
{ "uptime", &uptime_operations }, { "uptime", &uptime_operations, PROCFS_FILE_TYPE },
#endif #endif
}; };
@ -348,6 +353,7 @@ static int procfs_open(FAR struct file *filep, FAR const char *relpath,
((struct procfs_file_s *) filep->f_priv)->procfsentry = ((struct procfs_file_s *) filep->f_priv)->procfsentry =
&g_procfs_entries[x]; &g_procfs_entries[x];
break;
} }
} }
} }
@ -673,6 +679,7 @@ static int procfs_closedir(FAR struct inode *mountpt,
static int procfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) static int procfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
{ {
FAR const struct procfs_entry_s *entry = NULL;
FAR struct procfs_dir_priv_s *priv; FAR struct procfs_dir_priv_s *priv;
FAR struct procfs_level0_s *level0; FAR struct procfs_level0_s *level0;
FAR struct tcb_s *tcb; FAR struct tcb_s *tcb;
@ -705,7 +712,9 @@ static int procfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
while (index < priv->nentries + g_procfs_entrycount) while (index < priv->nentries + g_procfs_entrycount)
{ {
name = g_procfs_entries[index - priv->nentries].pathpattern; entry = &g_procfs_entries[index - priv->nentries];
name = entry->pathpattern;
while (*name != '/' && *name != '\0') while (*name != '/' && *name != '\0')
{ {
if (*name == '*' || *name == '[' || *name == '?') if (*name == '*' || *name == '[' || *name == '?')
@ -772,7 +781,7 @@ static int procfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
strncpy(dir->fd_dir.d_name, name, level0->lastlen); strncpy(dir->fd_dir.d_name, name, level0->lastlen);
dir->fd_dir.d_name[level0->lastlen] = '\0'; dir->fd_dir.d_name[level0->lastlen] = '\0';
if (name[level0->lastlen] == '/') if (entry->type == PROCFS_DIR_TYPE)
{ {
dir->fd_dir.d_type = DTYPE_DIRECTORY; dir->fd_dir.d_type = DTYPE_DIRECTORY;
} }

View File

@ -93,6 +93,15 @@ struct procfs_operations
/* Procfs handler prototypes ************************************************/ /* Procfs handler prototypes ************************************************/
/* These are the types of entries that may appear in the procfs: */
enum procfs_entry_e
{
PROCFS_UNKOWN_TYPE = 0, /* Unknown type */
PROCFS_FILE_TYPE, /* File type */
PROCFS_DIR_TYPE, /* Directory type */
};
/* This is a procfs entry that each handler should provide to supply /* This is a procfs entry that each handler should provide to supply
* specific operations for file and directory handling. * specific operations for file and directory handling.
*/ */
@ -101,6 +110,7 @@ struct procfs_entry_s
{ {
FAR const char *pathpattern; FAR const char *pathpattern;
FAR const struct procfs_operations *ops; FAR const struct procfs_operations *ops;
uint8_t type;
}; };
/* Specifies the common elements for an open file in the procfs /* Specifies the common elements for an open file in the procfs

View File

@ -47,6 +47,12 @@ ifeq ($(CONFIG_NET_STATISTICS),y)
NET_CSRCS += net_statistics.c NET_CSRCS += net_statistics.c
endif endif
# Routing table
ifeq ($(CONFIG_NET_ROUTE),y)
NET_CSRCS += net_procfs_route.c
endif
# Include packet socket build support # Include packet socket build support
DEPPATH += --dep-path procfs DEPPATH += --dep-path procfs

View File

@ -56,6 +56,7 @@
#include <nuttx/fs/fs.h> #include <nuttx/fs/fs.h>
#include <nuttx/fs/procfs.h> #include <nuttx/fs/procfs.h>
#include <nuttx/fs/dirent.h> #include <nuttx/fs/dirent.h>
#include <nuttx/lib/regex.h>
#include <nuttx/net/netdev.h> #include <nuttx/net/netdev.h>
#include "netdev/netdev.h" #include "netdev/netdev.h"
@ -64,6 +65,26 @@
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_PROCFS) && \ #if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_PROCFS) && \
!defined(CONFIG_FS_PROCFS_EXCLUDE_NET) !defined(CONFIG_FS_PROCFS_EXCLUDE_NET)
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Directory entry indices */
#if defined(CONFIG_NET_STATISTICS) && defined(CONFIG_NET_ROUTE)
# define STAT_INDEX 0
# define ROUTE_INDEX 1
# define DEV_INDEX 2
#elif defined(CONFIG_NET_STATISTICS)
# define STAT_INDEX 0
# define DEV_INDEX 1
#elif defined(CONFIG_NET_ROUTE)
# define ROUTE_INDEX 0
# define DEV_INDEX 1
#else
# define DEV_INDEX 0
#endif
/**************************************************************************** /****************************************************************************
* Private Function Prototypes * Private Function Prototypes
****************************************************************************/ ****************************************************************************/
@ -112,6 +133,8 @@ const struct procfs_operations net_procfsoperations =
netprocfs_stat /* stat */ netprocfs_stat /* stat */
}; };
extern const struct procfs_operations net_procfs_routeoperations;
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
@ -125,6 +148,7 @@ static int netprocfs_open(FAR struct file *filep, FAR const char *relpath,
{ {
FAR struct netprocfs_file_s *priv; FAR struct netprocfs_file_s *priv;
FAR struct net_driver_s *dev; FAR struct net_driver_s *dev;
enum netprocfs_entry_e entry;
finfo("Open '%s'\n", relpath); finfo("Open '%s'\n", relpath);
@ -141,18 +165,29 @@ static int netprocfs_open(FAR struct file *filep, FAR const char *relpath,
return -EACCES; return -EACCES;
} }
#ifdef CONFIG_NET_STATISTICS
/* "net/stat" is an acceptable value for the relpath only if network layer /* "net/stat" is an acceptable value for the relpath only if network layer
* statistics are enabled. * statistics are enabled.
*/ */
#ifdef CONFIG_NET_STATISTICS
if (strcmp(relpath, "net/stat") == 0) if (strcmp(relpath, "net/stat") == 0)
{ {
/* A NULL network device reference is a clue that we are processing entry = NETPROCFS_SUBDIR_STAT;
* the network statistics file. dev = NULL;
}
else
#endif
#ifdef CONFIG_NET_ROUTE
/* "net/route" is an acceptable value for the relpath only if routing
* table support is initialized.
*/ */
dev = NULL; if (match("net/route/**", relpath))
{
/* Use the /net/route directory */
return net_procfs_routeoperations.open(filep, relpath, oflags, mode);
} }
else else
#endif #endif
@ -180,11 +215,14 @@ static int netprocfs_open(FAR struct file *filep, FAR const char *relpath,
ferr("ERROR: relpath is '%s'\n", relpath); ferr("ERROR: relpath is '%s'\n", relpath);
return -ENOENT; return -ENOENT;
} }
entry = NETPROCFS_SUBDIR_DEV;
} }
/* Allocate the open file structure */ /* Allocate the open file structure */
priv = (FAR struct netprocfs_file_s *)kmm_zalloc(sizeof(struct netprocfs_file_s)); priv = (FAR struct netprocfs_file_s *)
kmm_zalloc(sizeof(struct netprocfs_file_s));
if (!priv) if (!priv)
{ {
ferr("ERROR: Failed to allocate file attributes\n"); ferr("ERROR: Failed to allocate file attributes\n");
@ -194,6 +232,7 @@ static int netprocfs_open(FAR struct file *filep, FAR const char *relpath,
/* Initialize the open-file structure */ /* Initialize the open-file structure */
priv->dev = dev; priv->dev = dev;
priv->entry = entry;
/* Save the open file structure as the open-specific state in /* Save the open file structure as the open-specific state in
* filep->f_priv. * filep->f_priv.
@ -240,23 +279,32 @@ static ssize_t netprocfs_read(FAR struct file *filep, FAR char *buffer,
priv = (FAR struct netprocfs_file_s *)filep->f_priv; priv = (FAR struct netprocfs_file_s *)filep->f_priv;
DEBUGASSERT(priv); DEBUGASSERT(priv);
#ifdef CONFIG_NET_STATISTICS /* Read according to the sub-directory */
/* A NULL device structure reference is the key that we are showing the
* network statistics.
*/
if (priv->dev == NULL) switch (priv->entry)
{ {
case NETPROCFS_SUBDIR_DEV:
/* Show device-specific statistics */
nreturned = netprocfs_read_devstats(priv, buffer, buflen);
break;
#ifdef CONFIG_NET_STATISTICS
case NETPROCFS_SUBDIR_STAT:
/* Show the network layer statistics */ /* Show the network layer statistics */
nreturned = netprocfs_read_netstats(priv, buffer, buflen); nreturned = netprocfs_read_netstats(priv, buffer, buflen);
} break;
else
#endif #endif
{
/* Otherwise, we are showing device-specific statistics */
nreturned = netprocfs_read_devstats(priv, buffer, buflen); #ifdef CONFIG_NET_ROUTE
case NETPROCFS_SUBDIR_ROUTE:
nerr("ERROR: Cannot read from directory net/route\n");
#endif
default:
nerr("ERROR: Invalid entry for reading: %u\n", priv->entry);
nreturned = -EINVAL;
} }
/* Update the file offset */ /* Update the file offset */
@ -321,13 +369,56 @@ static int netprocfs_opendir(FAR const char *relpath,
{ {
FAR struct netprocfs_level1_s *level1; FAR struct netprocfs_level1_s *level1;
int ndevs; int ndevs;
int ret;
finfo("relpath: \"%s\"\n", relpath ? relpath : "NULL"); finfo("relpath: \"%s\"\n", relpath ? relpath : "NULL");
DEBUGASSERT(relpath && dir && !dir->u.procfs); DEBUGASSERT(relpath && dir && !dir->u.procfs);
/* "net" is the only value of relpath that is a directory */ /* "net" and "net/route" are the only values of relpath that are
* directories.
*/
if (strcmp(relpath, "net") != 0) #ifdef CONFIG_NET_ROUTE
if (match("net/route", relpath) || match("net/route/**", relpath))
{
/* Use the /net/route directory */
return net_procfs_routeoperations.opendir(relpath, dir);
}
#endif
/* Assume that path refers to the 1st level subdirectory. Allocate the
* level1 the dirent structure before checking.
*/
level1 = (FAR struct netprocfs_level1_s *)
kmm_zalloc(sizeof(struct netprocfs_level1_s));
if (level1 == NULL)
{
ferr("ERROR: Failed to allocate the level1 directory structure\n");
return -ENOMEM;
}
level1->base.level = 1;
if (strcmp(relpath, "net") == 0)
{
/* Count the number of network devices */
ndevs = netdev_count();
/* Initialze base structure components */
level1->base.nentries = ndevs;
#ifdef CONFIG_NET_STATISTICS
level1->base.nentries++;
#endif
#ifdef CONFIG_NET_ROUTE
level1->base.nentries++;
#endif
}
else
{ {
/* REVISIT: We really need to check if the relpath refers to a network /* REVISIT: We really need to check if the relpath refers to a network
* device. In that case, we need to return -ENOTDIR. Otherwise, we * device. In that case, we need to return -ENOTDIR. Otherwise, we
@ -335,38 +426,16 @@ static int netprocfs_opendir(FAR const char *relpath,
*/ */
ferr("ERROR: Bad relpath: %s\n", relpath); ferr("ERROR: Bad relpath: %s\n", relpath);
return -ENOTDIR; ret = -ENOTDIR;
goto errout_with_alloc;
} }
/* The path refers to the 1st level sbdirectory. Allocate the level1 dir->u.procfs = (FAR void *)level1;
* dirent structure.
*/
level1 = (FAR struct netprocfs_level1_s *)
kmm_zalloc(sizeof(struct netprocfs_level1_s));
if (!level1)
{
ferr("ERROR: Failed to allocate the level1 directory structure\n");
return -ENOMEM;
}
/* Count the number of network devices */
ndevs = netdev_count();
/* Initialze base structure components */
level1->base.level = 1;
#ifdef CONFIG_NET_STATISTICS
level1->base.nentries = ndevs + 1;
#else
level1->base.nentries = ndevs;
#endif
level1->base.index = 0;
dir->u.procfs = (FAR void *) level1;
return OK; return OK;
errout_with_alloc:
kmm_free(level1);
return ret;
} }
/**************************************************************************** /****************************************************************************
@ -404,12 +473,19 @@ static int netprocfs_readdir(FAR struct fs_dirent_s *dir)
FAR struct netprocfs_level1_s *level1; FAR struct netprocfs_level1_s *level1;
FAR struct net_driver_s *dev; FAR struct net_driver_s *dev;
int index; int index;
int ret;
DEBUGASSERT(dir && dir->u.procfs); DEBUGASSERT(dir && dir->u.procfs);
level1 = dir->u.procfs; level1 = dir->u.procfs;
DEBUGASSERT(level1->base.level == 1); DEBUGASSERT(level1->base.level > 0);
/* Have we reached the end of the directory */ /* Are we searching this directory? Or is it just an intermediate on the
* way to a sub-directory?
*/
if (level1->base.level == 1)
{
/* This directory.. Have we reached the end of the directory? */
index = level1->base.index; index = level1->base.index;
DEBUGASSERT(index <= level1->base.nentries); DEBUGASSERT(index <= level1->base.nentries);
@ -425,7 +501,7 @@ static int netprocfs_readdir(FAR struct fs_dirent_s *dir)
} }
#ifdef CONFIG_NET_STATISTICS #ifdef CONFIG_NET_STATISTICS
else if (index == 0) else if (index == STAT_INDEX)
{ {
/* Copy the network statistics directory entry */ /* Copy the network statistics directory entry */
@ -434,16 +510,18 @@ static int netprocfs_readdir(FAR struct fs_dirent_s *dir)
} }
else else
#endif #endif
#ifdef CONFIG_NET_ROUTE
if (index == ROUTE_INDEX)
{ {
int devndx = index; /* Copy the network statistics directory entry */
#ifdef CONFIG_NET_STATISTICS dir->fd_dir.d_type = DTYPE_DIRECTORY;
/* Subtract one to account for index == 0 which is used for network strncpy(dir->fd_dir.d_name, "route", NAME_MAX + 1);
* status. }
*/ else
devndx--;
#endif #endif
{
int devndx = index - DEV_INDEX;
/* Find the device corresponding to this device index */ /* Find the device corresponding to this device index */
@ -460,7 +538,21 @@ static int netprocfs_readdir(FAR struct fs_dirent_s *dir)
*/ */
level1->base.index = index + 1; level1->base.index = index + 1;
return OK; ret = OK;
}
else
{
/* We are performing a directory search of one of the subdirectories
* and we must let the handler perform the read.
*/
DEBUGASSERT(level1->base.procfsentry != NULL &&
level1->base.procfsentry->ops->readdir != NULL);
ret = level1->base.procfsentry->ops->readdir(dir);
}
return ret;
} }
/**************************************************************************** /****************************************************************************
@ -505,6 +597,15 @@ static int netprocfs_stat(FAR const char *relpath, FAR struct stat *buf)
buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR; buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR;
} }
else else
#endif
#ifdef CONFIG_NET_ROUTE
/* Check for network statistics "net/stat" */
if (strcmp(relpath, "net/route") == 0)
{
buf->st_mode = S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR;
}
else
#endif #endif
{ {
FAR struct net_driver_s *dev; FAR struct net_driver_s *dev;

View File

@ -82,7 +82,7 @@ static int netprocfs_retransmissions(FAR struct netprocfs_file_s *netfile);
/* Line generating functions */ /* Line generating functions */
static const linegen_t g_linegen[] = static const linegen_t g_stat_linegen[] =
{ {
netprocfs_header, netprocfs_header,
netprocfs_received, netprocfs_received,
@ -111,7 +111,7 @@ static const linegen_t g_linegen[] =
#endif /* CONFIG_NET_TCP */ #endif /* CONFIG_NET_TCP */
}; };
#define NSTAT_LINES (sizeof(g_linegen) / sizeof(linegen_t)) #define NSTAT_LINES (sizeof(g_stat_linegen) / sizeof(linegen_t))
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
@ -456,7 +456,7 @@ static int netprocfs_retransmissions(FAR struct netprocfs_file_s *netfile)
ssize_t netprocfs_read_netstats(FAR struct netprocfs_file_s *priv, ssize_t netprocfs_read_netstats(FAR struct netprocfs_file_s *priv,
FAR char *buffer, size_t buflen) FAR char *buffer, size_t buflen)
{ {
return netprocfs_read_linegen(priv, buffer, buflen, g_linegen, NSTAT_LINES); return netprocfs_read_linegen(priv, buffer, buflen, g_stat_linegen, NSTAT_LINES);
} }
#endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_FS_PROCFS && #endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_FS_PROCFS &&

View File

@ -84,7 +84,7 @@ static int netprocfs_errors(FAR struct netprocfs_file_s *netfile);
/* Line generating functions */ /* Line generating functions */
static const linegen_t g_linegen[] = static const linegen_t g_netstat_linegen[] =
{ {
netprocfs_linklayer netprocfs_linklayer
#ifdef CONFIG_NET_IPv4 #ifdef CONFIG_NET_IPv4
@ -105,7 +105,7 @@ static const linegen_t g_linegen[] =
#endif /* CONFIG_NETDEV_STATISTICS */ #endif /* CONFIG_NETDEV_STATISTICS */
}; };
#define NSTAT_LINES (sizeof(g_linegen) / sizeof(linegen_t)) #define NSTAT_LINES (sizeof(g_netstat_linegen) / sizeof(linegen_t))
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
@ -554,7 +554,8 @@ static int netprocfs_errors(FAR struct netprocfs_file_s *netfile)
ssize_t netprocfs_read_devstats(FAR struct netprocfs_file_s *priv, ssize_t netprocfs_read_devstats(FAR struct netprocfs_file_s *priv,
FAR char *buffer, size_t buflen) FAR char *buffer, size_t buflen)
{ {
return netprocfs_read_linegen(priv, buffer, buflen, g_linegen, NSTAT_LINES); return netprocfs_read_linegen(priv, buffer, buflen, g_netstat_linegen,
NSTAT_LINES);
} }
#endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_FS_PROCFS && #endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_FS_PROCFS &&

View File

@ -50,6 +50,10 @@
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_FS_PROCFS_EXCLUDE_ROUTE
# undef CONFIG_NET_ROUTE
#endif
/* Determines the size of an intermediate buffer that must be large enough /* Determines the size of an intermediate buffer that must be large enough
* to handle the longest line generated by this logic. * to handle the longest line generated by this logic.
*/ */
@ -60,6 +64,19 @@
* Public Type Definitions * Public Type Definitions
****************************************************************************/ ****************************************************************************/
/* Describes the /net directory entries */
enum netprocfs_entry_e
{
NETPROCFS_SUBDIR_DEV = 0 /* Multiple instances, e.g. /proc/net/eth0 */
#ifdef CONFIG_NET_STATISTICS
, NETPROCFS_SUBDIR_STAT /* /proc/net/stat */
#endif
#ifdef CONFIG_NET_ROUTE
, NETPROCFS_SUBDIR_ROUTE /* /proc/net/route */
#endif
};
/* This structure describes one open "file" */ /* This structure describes one open "file" */
struct net_driver_s; /* Forward reference */ struct net_driver_s; /* Forward reference */
@ -70,6 +87,7 @@ struct netprocfs_file_s
uint8_t lineno; /* Line number */ uint8_t lineno; /* Line number */
uint8_t linesize; /* Number of valid characters in line[] */ uint8_t linesize; /* Number of valid characters in line[] */
uint8_t offset; /* Offset to first valid character in line[] */ uint8_t offset; /* Offset to first valid character in line[] */
uint8_t entry; /* See enum netprocfs_entry_e */
char line[NET_LINELEN]; /* Pre-allocated buffer for formatted lines */ char line[NET_LINELEN]; /* Pre-allocated buffer for formatted lines */
}; };
@ -148,6 +166,29 @@ ssize_t netprocfs_read_netstats(FAR struct netprocfs_file_s *priv,
FAR char *buffer, size_t buflen); FAR char *buffer, size_t buflen);
#endif #endif
/****************************************************************************
* Name: netprocfs_read_routes
*
* Description:
* Read and format routing table entries.
*
* Input Parameters:
* priv - A reference to the network procfs file structure
* buffer - The user-provided buffer into which network status will be
* returned.
* bulen - The size in bytes of the user provided buffer.
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned
* on failure.
*
****************************************************************************/
#ifdef CONFIG_NET_ROUTE
ssize_t netprocfs_read_routes(FAR struct netprocfs_file_s *priv,
FAR char *buffer, size_t buflen);
#endif
/**************************************************************************** /****************************************************************************
* Name: netprocfs_read_devstats * Name: netprocfs_read_devstats
* *