net/procfs: add entry mapping table

add entry mapping table to simplify new component registration

Signed-off-by: chao an <anchao@xiaomi.com>
This commit is contained in:
chao an 2022-09-04 21:39:06 +08:00 committed by Xiang Xiao
parent 3913ef2f2f
commit 4068b2eccc
2 changed files with 130 additions and 181 deletions

View File

@ -52,26 +52,27 @@
* Pre-processor Definitions
****************************************************************************/
/* Directory entry indices */
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#ifdef CONFIG_NET_STATISTICS
# define STAT_INDEX 0
# ifdef CONFIG_NET_MLD
# define MLD_INDEX 1
# define _ROUTE_INDEX 2
# else
# define _ROUTE_INDEX 1
# endif
#else
# define _ROUTE_INDEX 0
#endif
/****************************************************************************
* Private Type Definitions
****************************************************************************/
#ifdef CONFIG_NET_ROUTE
# define ROUTE_INDEX _ROUTE_INDEX
# define DEV_INDEX (_ROUTE_INDEX + 1)
#else
# define DEV_INDEX _ROUTE_INDEX
#endif
/* Read statistics function type */
typedef CODE ssize_t (*read_stat_t)(FAR struct netprocfs_file_s *priv,
FAR char *buffer, size_t buflen);
struct netprocfs_entry_s
{
uint8_t type; /* Type of file */
FAR const char *name; /* File name */
union
{
read_stat_t stat; /* Read statistics hook */
FAR const struct procfs_operations *ops;
} u;
};
/****************************************************************************
* Private Function Prototypes
@ -98,6 +99,48 @@ static int netprocfs_rewinddir(FAR struct fs_dirent_s *dir);
static int netprocfs_stat(FAR const char *relpath, FAR struct stat *buf);
/****************************************************************************
* Private Data
****************************************************************************/
extern const struct procfs_operations net_procfs_routeoperations;
/* Netprocfs component mappings */
static const struct netprocfs_entry_s g_net_entries[] =
{
#ifdef CONFIG_NET_STATISTICS
{
DTYPE_FILE, "stat",
{
netprocfs_read_netstats
}
},
# ifdef CONFIG_NET_MLD
{
DTYPE_FILE, "mld",
{
netprocfs_read_mldstats
}
},
# endif
#endif
#ifdef CONFIG_NET_ROUTE
{
DTYPE_DIRECTORY, "route",
{
(FAR void *)&net_procfs_routeoperations
}
},
#endif
{
DTYPE_FILE, "",
{
netprocfs_read_devstats
}
}
};
/****************************************************************************
* Public Data
****************************************************************************/
@ -123,8 +166,6 @@ const struct procfs_operations net_procfsoperations =
netprocfs_stat /* stat */
};
extern const struct procfs_operations net_procfs_routeoperations;
/****************************************************************************
* Private Functions
****************************************************************************/
@ -136,9 +177,9 @@ extern const struct procfs_operations net_procfs_routeoperations;
static int netprocfs_open(FAR struct file *filep, FAR const char *relpath,
int oflags, mode_t mode)
{
FAR struct net_driver_s *dev = NULL;
FAR struct netprocfs_file_s *priv;
FAR struct net_driver_s *dev;
enum netprocfs_entry_e entry;
int i;
finfo("Open '%s'\n", relpath);
@ -155,44 +196,25 @@ static int netprocfs_open(FAR struct file *filep, FAR const char *relpath,
return -EACCES;
}
#ifdef CONFIG_NET_STATISTICS
/* "net/stat" is an acceptable value for the relpath only if network layer
* statistics are enabled.
*/
/* For each net entries */
if (strcmp(relpath, "net/stat") == 0)
for (i = 0; i < ARRAY_SIZE(g_net_entries); i++)
{
entry = NETPROCFS_SUBDIR_STAT;
dev = NULL;
if (strncmp(relpath + 4, g_net_entries[i].name,
strlen(g_net_entries[i].name)))
{
continue;
}
if (g_net_entries[i].type == DTYPE_DIRECTORY)
{
return g_net_entries[i].u.ops->open(filep, relpath, oflags, mode);
}
break;
}
else
#ifdef CONFIG_NET_MLD
/* "net/mld" is an acceptable value for the relpath only if MLD is
* enabled.
*/
if (strcmp(relpath, "net/mld") == 0)
{
entry = NETPROCFS_SUBDIR_MLD;
dev = NULL;
}
else
#endif
#endif
#ifdef CONFIG_NET_ROUTE
/* "net/route" is an acceptable value for the relpath only if routing
* table support is initialized.
*/
if (fnmatch("net/route/**", relpath, 0) == 0)
{
/* Use the /net/route directory */
return net_procfs_routeoperations.open(filep, relpath, oflags, mode);
}
else
#endif
if (i == ARRAY_SIZE(g_net_entries) - 1)
{
FAR char *devname;
FAR char *copy;
@ -217,8 +239,6 @@ static int netprocfs_open(FAR struct file *filep, FAR const char *relpath,
ferr("ERROR: relpath is '%s'\n", relpath);
return -ENOENT;
}
entry = NETPROCFS_SUBDIR_DEV;
}
/* Allocate the open file structure */
@ -234,7 +254,7 @@ static int netprocfs_open(FAR struct file *filep, FAR const char *relpath,
/* Initialize the open-file structure */
priv->dev = dev;
priv->entry = entry;
priv->entry = i;
/* Save the open file structure as the open-specific state in
* filep->f_priv.
@ -272,7 +292,7 @@ static ssize_t netprocfs_read(FAR struct file *filep, FAR char *buffer,
size_t buflen)
{
FAR struct netprocfs_file_s *priv;
ssize_t nreturned;
ssize_t nreturned = -EINVAL;
finfo("buffer=%p buflen=%lu\n", buffer, (unsigned long)buflen);
@ -283,42 +303,8 @@ static ssize_t netprocfs_read(FAR struct file *filep, FAR char *buffer,
/* Read according to the sub-directory */
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 */
nreturned = netprocfs_read_netstats(priv, buffer, buflen);
break;
#ifdef CONFIG_NET_MLD
case NETPROCFS_SUBDIR_MLD:
/* Show the MLD statistics */
nreturned = netprocfs_read_mldstats(priv, buffer, buflen);
break;
#endif
#endif
#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;
}
nreturned = g_net_entries[priv->entry].u.stat(priv,
buffer, buflen);
/* Update the file offset */
@ -384,23 +370,28 @@ static int netprocfs_opendir(FAR const char *relpath,
FAR struct netprocfs_level1_s *level1;
int ndevs;
int ret;
int i;
finfo("relpath: \"%s\"\n", relpath ? relpath : "NULL");
DEBUGASSERT(relpath && dir);
/* "net" and "net/route" are the only values of relpath that are
* directories.
*/
/* Subdirectory ? */
#ifdef CONFIG_NET_ROUTE
if (fnmatch("net/route", relpath, 0) == 0 ||
fnmatch("net/route/**", relpath, 0) == 0)
for (i = 0; i < ARRAY_SIZE(g_net_entries); i++)
{
/* Use the /net/route directory */
if (strncmp(relpath + 4, g_net_entries[i].name,
strlen(g_net_entries[i].name)))
{
continue;
}
return net_procfs_routeoperations.opendir(relpath, dir);
if (g_net_entries[i].type == DTYPE_DIRECTORY)
{
return g_net_entries[i].u.ops->opendir(relpath, dir);
}
break;
}
#endif
/* Assume that path refers to the 1st level subdirectory. Allocate the
* level1 the dirent structure before checking.
@ -426,15 +417,10 @@ static int netprocfs_opendir(FAR const char *relpath,
/* Initialize base structure components */
level1->base.nentries = ndevs;
#ifdef CONFIG_NET_STATISTICS
level1->base.nentries++;
#ifdef CONFIG_NET_MLD
level1->base.nentries++;
#endif
#endif
#ifdef CONFIG_NET_ROUTE
level1->base.nentries++;
#endif
/* Add other enabled net components, except netdev */
level1->base.nentries += ARRAY_SIZE(g_net_entries) - 1;
}
else
{
@ -510,36 +496,18 @@ static int netprocfs_readdir(FAR struct fs_dirent_s *dir,
return -ENOENT;
}
#ifdef CONFIG_NET_STATISTICS
if (index == STAT_INDEX)
{
/* Copy the network statistics directory entry */
/* Process other enabled net components, except netdev */
entry->d_type = DTYPE_FILE;
strlcpy(entry->d_name, "stat", sizeof(entry->d_name));
}
else
#ifdef CONFIG_NET_MLD
if (index == MLD_INDEX)
if (index < ARRAY_SIZE(g_net_entries) - 1)
{
/* Copy the MLD directory entry */
entry->d_type = DTYPE_FILE;
strlcpy(entry->d_name, "mld", sizeof(entry->d_name));
entry->d_type = g_net_entries[index].type;
strlcpy(entry->d_name,
g_net_entries[index].name, sizeof(entry->d_name));
}
else
#endif
#endif
#ifdef CONFIG_NET_ROUTE
if (index == ROUTE_INDEX)
{
/* Copy the network statistics directory entry */
entry->d_type = DTYPE_DIRECTORY;
strlcpy(entry->d_name, "route", sizeof(entry->d_name));
}
/* Net device entry */
else
#endif
{
int ifindex;
@ -567,9 +535,9 @@ static int netprocfs_readdir(FAR struct fs_dirent_s *dir,
level1->ifindex = ifindex + 1;
#else
/* Get the raw index, accounting for 1 based indexing */
/* Get the raw index */
ifindex = index - DEV_INDEX + 1;
ifindex = index - ARRAY_SIZE(g_net_entries) + 1;
#endif
/* Find the device corresponding to this device index */
@ -636,40 +604,37 @@ static int netprocfs_rewinddir(FAR struct fs_dirent_s *dir)
static int netprocfs_stat(FAR const char *relpath, FAR struct stat *buf)
{
int i;
/* Check for the directory "net" */
buf->st_mode = 0;
if (strcmp(relpath, "net") == 0 || strcmp(relpath, "net/") == 0)
{
buf->st_mode = S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR;
}
else
#ifdef CONFIG_NET_STATISTICS
/* Check for network statistics "net/stat" */
if (strcmp(relpath, "net/stat") == 0)
{
buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR;
}
else
#ifdef CONFIG_NET_MLD
/* Check for MLD statistics "net/mld" */
for (i = 0; i < ARRAY_SIZE(g_net_entries); i++)
{
if (strcmp(relpath + 4, g_net_entries[i].name) == 0)
{
if (g_net_entries[i].type == DTYPE_FILE)
{
buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR;
}
else if (g_net_entries[i].type == DTYPE_DIRECTORY)
{
buf->st_mode = S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR;
}
if (strcmp(relpath, "net/mld") == 0)
{
buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR;
break;
}
}
}
else
#endif
#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
if (buf->st_mode == 0)
{
FAR struct net_driver_s *dev;
FAR char *devname;

View File

@ -49,22 +49,6 @@
* 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 */
#ifdef CONFIG_NET_MLD
, NETPROCFS_SUBDIR_MLD /* /proc/net/mld */
#endif
#endif
#ifdef CONFIG_NET_ROUTE
, NETPROCFS_SUBDIR_ROUTE /* /proc/net/route */
#endif
};
/* This structure describes one open "file" */
struct net_driver_s; /* Forward reference */
@ -75,7 +59,7 @@ struct netprocfs_file_s
uint8_t lineno; /* Line number */
uint8_t linesize; /* Number of valid characters in line[] */
uint8_t offset; /* Offset to first valid character in line[] */
uint8_t entry; /* See enum netprocfs_entry_e */
uint8_t entry; /* Entry index of netprocfs_entry_s */
char line[NET_LINELEN]; /* Pre-allocated buffer for formatted lines */
};