From cb958e5d695f2f5a2816d6b35e38fdabdf6a2042 Mon Sep 17 00:00:00 2001 From: Zhe Weng Date: Thu, 22 Dec 2022 11:35:02 +0800 Subject: [PATCH] net/nat: Clear entries when NAT will be disabled Signed-off-by: Zhe Weng --- net/nat/ipv4_nat.c | 14 +++++++++++++- net/nat/ipv4_nat_entry.c | 35 +++++++++++++++++++++++++++++++++++ net/nat/nat.h | 17 +++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/net/nat/ipv4_nat.c b/net/nat/ipv4_nat.c index 93709b705f..8f615f9f8c 100644 --- a/net/nat/ipv4_nat.c +++ b/net/nat/ipv4_nat.c @@ -687,13 +687,18 @@ ipv4_nat_outbound_internal(FAR struct net_driver_s *dev, int ipv4_nat_enable(FAR struct net_driver_s *dev) { + net_lock(); + if (IFF_IS_NAT(dev->d_flags)) { nwarn("WARNING: NAT was already enabled for %s!\n", dev->d_ifname); + net_unlock(); return -EEXIST; } IFF_SET_NAT(dev->d_flags); + + net_unlock(); return OK; } @@ -714,15 +719,22 @@ int ipv4_nat_enable(FAR struct net_driver_s *dev) int ipv4_nat_disable(FAR struct net_driver_s *dev) { + net_lock(); + if (!IFF_IS_NAT(dev->d_flags)) { nwarn("WARNING: NAT was not enabled for %s!\n", dev->d_ifname); + net_unlock(); return -ENODEV; } - /* TODO: Clear entries related to dev. */ + /* Clear entries related to dev. */ + + ipv4_nat_entry_clear(dev); IFF_CLR_NAT(dev->d_flags); + + net_unlock(); return OK; } diff --git a/net/nat/ipv4_nat_entry.c b/net/nat/ipv4_nat_entry.c index e9e8e5e484..fa106161b6 100644 --- a/net/nat/ipv4_nat_entry.c +++ b/net/nat/ipv4_nat_entry.c @@ -410,6 +410,41 @@ static void ipv4_nat_reclaim_entry(int32_t current_time) * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: ipv4_nat_entry_clear + * + * Description: + * Clear all entries related to dev. Called when NAT will be disabled on + * any device. + * + * Input Parameters: + * dev - The device on which NAT entries will be cleared. + * + * Assumptions: + * NAT is initialized. + * + ****************************************************************************/ + +void ipv4_nat_entry_clear(FAR struct net_driver_s *dev) +{ + FAR hash_node_t *p; + FAR hash_node_t *tmp; + int i; + + ninfo("INFO: Clearing all NAT entries for %s\n", dev->d_ifname); + + 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 (net_ipv4addr_cmp(entry->external_ip, dev->d_ipaddr)) + { + ipv4_nat_entry_delete(entry); + } + } +} + /**************************************************************************** * Name: ipv4_nat_inbound_entry_find * diff --git a/net/nat/nat.h b/net/nat/nat.h index ffedf5c1dc..4c70ceeb95 100644 --- a/net/nat/nat.h +++ b/net/nat/nat.h @@ -176,6 +176,23 @@ int ipv4_nat_outbound(FAR struct net_driver_s *dev, bool ipv4_nat_port_inuse(uint8_t protocol, in_addr_t ip, uint16_t port); +/**************************************************************************** + * Name: ipv4_nat_entry_clear + * + * Description: + * Clear all entries related to dev. Called when NAT will be disabled on + * any device. + * + * Input Parameters: + * dev - The device on which NAT entries will be cleared. + * + * Assumptions: + * NAT is initialized. + * + ****************************************************************************/ + +void ipv4_nat_entry_clear(FAR struct net_driver_s *dev); + /**************************************************************************** * Name: ipv4_nat_inbound_entry_find *