net/nat: Add auto reclaim logic for NAT entries.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
This commit is contained in:
parent
879c337e30
commit
a9da1fff28
@ -53,3 +53,17 @@ config NET_NAT_ICMP_EXPIRE_SEC
|
||||
|
||||
Note: The default value 60 is suggested by RFC5508, Section 3.2,
|
||||
Page 8.
|
||||
|
||||
config NET_NAT_ENTRY_RECLAIM_SEC
|
||||
int "The time to auto reclaim all expired entries"
|
||||
default 3600
|
||||
depends on NET_NAT
|
||||
---help---
|
||||
The time to auto reclaim all expired entries. A value of zero will
|
||||
disable auto reclaiming.
|
||||
|
||||
Note: Expired entries will be automatically reclaimed when matching
|
||||
inbound/outbound entries, so this config does not have significant
|
||||
impact when NAT is normally used, but very useful when the hashtable
|
||||
is big and there are only a few connections using NAT (which will
|
||||
only trigger reclaiming on a few chains in hashtable).
|
||||
|
@ -352,6 +352,54 @@ static void ipv4_nat_entry_delete(FAR struct ipv4_nat_entry *entry)
|
||||
kmm_free(entry);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ipv4_nat_reclaim_entry
|
||||
*
|
||||
* Description:
|
||||
* Try reclaim all expired NAT entries.
|
||||
* Only works after every CONFIG_NET_NAT_ENTRY_RECLAIM_SEC (low frequency).
|
||||
*
|
||||
* Although expired entries will be automatically reclaimed when matching
|
||||
* inbound/outbound entries, there might be some situations that entries
|
||||
* will be kept in memory, e.g. big hashtable with only a few connections.
|
||||
*
|
||||
* Assumptions:
|
||||
* NAT is initialized.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NET_NAT_ENTRY_RECLAIM_SEC > 0
|
||||
static void ipv4_nat_reclaim_entry(int32_t current_time)
|
||||
{
|
||||
static int32_t next_reclaim_time = CONFIG_NET_NAT_ENTRY_RECLAIM_SEC;
|
||||
|
||||
if (next_reclaim_time - current_time <= 0)
|
||||
{
|
||||
FAR hash_node_t *p;
|
||||
FAR hash_node_t *tmp;
|
||||
int count = 0;
|
||||
int i;
|
||||
|
||||
ninfo("INFO: Reclaiming all expired NAT entries.\n");
|
||||
|
||||
hashtable_for_every_safe(g_table_inbound, p, tmp, i)
|
||||
{
|
||||
FAR struct ipv4_nat_entry *entry =
|
||||
container_of(p, struct ipv4_nat_entry, hash_inbound);
|
||||
|
||||
if (entry->expire_time - current_time <= 0)
|
||||
{
|
||||
ipv4_nat_entry_delete(entry);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
ninfo("INFO: %d expired NAT entries reclaimed.\n", count);
|
||||
next_reclaim_time = current_time + CONFIG_NET_NAT_ENTRY_RECLAIM_SEC;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -378,7 +426,11 @@ ipv4_nat_inbound_entry_find(uint8_t protocol, uint16_t external_port,
|
||||
{
|
||||
FAR hash_node_t *p;
|
||||
FAR hash_node_t *tmp;
|
||||
uint32_t current_time = TICK2SEC(clock_systime_ticks());
|
||||
int32_t current_time = TICK2SEC(clock_systime_ticks());
|
||||
|
||||
#if CONFIG_NET_NAT_ENTRY_RECLAIM_SEC > 0
|
||||
ipv4_nat_reclaim_entry(current_time);
|
||||
#endif
|
||||
|
||||
hashtable_for_every_possible_safe(g_table_inbound, p, tmp,
|
||||
ipv4_nat_inbound_key(external_port, protocol))
|
||||
@ -388,7 +440,7 @@ ipv4_nat_inbound_entry_find(uint8_t protocol, uint16_t external_port,
|
||||
|
||||
/* Remove expired entries. */
|
||||
|
||||
if (entry->expire_time < current_time)
|
||||
if (entry->expire_time - current_time <= 0)
|
||||
{
|
||||
ipv4_nat_entry_delete(entry);
|
||||
continue;
|
||||
@ -437,7 +489,11 @@ ipv4_nat_outbound_entry_find(FAR struct net_driver_s *dev, uint8_t protocol,
|
||||
{
|
||||
FAR hash_node_t *p;
|
||||
FAR hash_node_t *tmp;
|
||||
uint32_t current_time = TICK2SEC(clock_systime_ticks());
|
||||
int32_t current_time = TICK2SEC(clock_systime_ticks());
|
||||
|
||||
#if CONFIG_NET_NAT_ENTRY_RECLAIM_SEC > 0
|
||||
ipv4_nat_reclaim_entry(current_time);
|
||||
#endif
|
||||
|
||||
hashtable_for_every_possible_safe(g_table_outbound, p, tmp,
|
||||
ipv4_nat_outbound_key(local_ip, local_port, protocol))
|
||||
@ -447,7 +503,7 @@ ipv4_nat_outbound_entry_find(FAR struct net_driver_s *dev, uint8_t protocol,
|
||||
|
||||
/* Remove expired entries. */
|
||||
|
||||
if (entry->expire_time < current_time)
|
||||
if (entry->expire_time - current_time <= 0)
|
||||
{
|
||||
ipv4_nat_entry_delete(entry);
|
||||
continue;
|
||||
|
@ -63,7 +63,7 @@ struct ipv4_nat_entry
|
||||
uint16_t external_port; /* The external port of local (private) host. */
|
||||
uint8_t protocol; /* L4 protocol (TCP, UDP etc). */
|
||||
|
||||
uint32_t expire_time; /* The expiration time of this entry. */
|
||||
int32_t expire_time; /* The expiration time of this entry. */
|
||||
};
|
||||
|
||||
/* NAT IP/Port manipulate type, to indicate whether to manipulate source or
|
||||
|
Loading…
Reference in New Issue
Block a user