Skip to content

Commit

Permalink
net/netdev: Add an algorithm to prevent an interface index from being…
Browse files Browse the repository at this point in the history
… reused until all network interfaces have by assigned once. The prevents removable devices from being removed, unregistered and re-installed, re-registered and keeping the same interface index.
  • Loading branch information
gregory-nutt committed Jun 25, 2018
1 parent c65e1aa commit 5a0cf3c
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 18 deletions.
8 changes: 8 additions & 0 deletions net/netdev/netdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ EXTERN struct net_driver_s *g_netdevices;
*/

EXTERN uint32_t g_devset;

/* The set of network devices that have been freed. The purpose of this
* set is to postpone reuse of a interface index for as long as possible,
* i.e., don't reuse an interface index until all of the possible indices
* have been used.
*/

EXTERN uint32_t g_devfreed;
#endif

/****************************************************************************
Expand Down
52 changes: 36 additions & 16 deletions net/netdev/netdev_register.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@ struct net_driver_s *g_netdevices = NULL;
*/

uint32_t g_devset;

/* The set of network devices that have been freed. The purpose of this
* set is to postpone reuse of a interface index for as long as possible,
* i.e., don't reuse an interface index until all of the possible indices
* have been used.
*/

uint32_t g_devfreed;
#endif

/****************************************************************************
Expand Down Expand Up @@ -175,29 +183,41 @@ static int find_devnum(FAR const char *devfmt)
#ifdef CONFIG_NETDEV_IFINDEX
static int get_ifindex(void)
{
uint32_t devset;
int ndx;

/* Search for an unused index */
/* Try to postpone re-using interface indices as long as possible */

devset = g_devset | g_devfreed;
if (devset == 0xffffffff)
{
/* Time start re-using interface indices */

devset = g_devset;
g_devfreed = 0;
}

/* Search for an unused index */

for (ndx = 0; ndx < MAX_IFINDEX; ndx++)
{
uint32_t bit = 1L << ndx;
if ((g_devset & bit) == 0)
{
/* Indicate that this index is in use */
for (ndx = 0; ndx < MAX_IFINDEX; ndx++)
{
uint32_t bit = 1L << ndx;
if ((devset & bit) == 0)
{
/* Indicate that this index is in use */

g_devset |= bit;
g_devset |= bit;

/* NOTE that the index + 1 is returned. Zero is reserved to
* mean no-index in the POSIX standards.
*/
/* NOTE that the index + 1 is returned. Zero is reserved to
* mean no-index in the POSIX standards.
*/

net_unlock();
return ndx + 1;
}
}
net_unlock();
return ndx + 1;
}
}

return -ENOSPC;
return -ENOSPC;
}
#endif

Expand Down
5 changes: 3 additions & 2 deletions net/netdev/netdev_unregister.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,9 @@ static inline void free_ifindex(int ndx)

/* The bit should be in the set state */

DEBUGASSERT((g_devset & bit) != 0);
g_devset &= ~bit;
DEBUGASSERT((g_devset & bit) != 0 && (g_devfreed & bit) == 0);
g_devset &= ~bit;
g_devfreed |= bit;
}
#endif

Expand Down

0 comments on commit 5a0cf3c

Please sign in to comment.