From b0cf0acc666bda484a4e89edc14e2fa959476888 Mon Sep 17 00:00:00 2001 From: Zhe Weng Date: Thu, 21 Mar 2024 11:40:36 +0800 Subject: [PATCH] net/nat: Add foreach interface for entries Prepare for netlink conntrack dump of entries. Signed-off-by: Zhe Weng --- net/nat/ipv4_nat_entry.c | 76 +++++++++++++++++++++++++++------------- net/nat/ipv6_nat_entry.c | 76 +++++++++++++++++++++++++++------------- net/nat/nat.h | 24 +++++++++++++ 3 files changed, 126 insertions(+), 50 deletions(-) diff --git a/net/nat/ipv4_nat_entry.c b/net/nat/ipv4_nat_entry.c index ce86387f92..c961e1de86 100644 --- a/net/nat/ipv4_nat_entry.c +++ b/net/nat/ipv4_nat_entry.c @@ -195,32 +195,25 @@ static void ipv4_nat_entry_delete(FAR ipv4_nat_entry_t *entry) ****************************************************************************/ #if CONFIG_NET_NAT_ENTRY_RECLAIM_SEC > 0 +static void ipv4_nat_reclaim_entry_cb(FAR ipv4_nat_entry_t *entry, + FAR void *arg) +{ + int32_t current_time = *(FAR int32_t *)arg; + + if (entry->expire_time - current_time <= 0) + { + ipv4_nat_entry_delete(entry); + } +} + 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 NAT44 entries.\n"); - - hashtable_for_every_safe(g_nat44_inbound, p, tmp, i) - { - FAR ipv4_nat_entry_t *entry = - container_of(p, ipv4_nat_entry_t, hash_inbound); - - if (entry->expire_time - current_time <= 0) - { - ipv4_nat_entry_delete(entry); - count++; - } - } - - ninfo("INFO: %d expired NAT44 entries reclaimed.\n", count); + ipv4_nat_entry_foreach(ipv4_nat_reclaim_entry_cb, ¤t_time); next_reclaim_time = current_time + CONFIG_NET_NAT_ENTRY_RECLAIM_SEC; } } @@ -228,6 +221,26 @@ static void ipv4_nat_reclaim_entry(int32_t current_time) # define ipv4_nat_reclaim_entry(t) #endif +/**************************************************************************** + * Name: ipv4_nat_entry_clear_cb + * + * Description: + * Clear an entry related to dev. Called when NAT will be disabled on + * any device. + * + ****************************************************************************/ + +static void ipv4_nat_entry_clear_cb(FAR ipv4_nat_entry_t *entry, + FAR void *arg) +{ + FAR struct net_driver_s *dev = arg; + + if (net_ipv4addr_cmp(entry->external_ip, dev->d_ipaddr)) + { + ipv4_nat_entry_delete(entry); + } +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -248,22 +261,35 @@ static void ipv4_nat_reclaim_entry(int32_t current_time) ****************************************************************************/ void ipv4_nat_entry_clear(FAR struct net_driver_s *dev) +{ + ninfo("INFO: Clearing all NAT44 entries for %s\n", dev->d_ifname); + ipv4_nat_entry_foreach(ipv4_nat_entry_clear_cb, dev); +} + +/**************************************************************************** + * Name: ipv4_nat_entry_foreach + * + * Description: + * Call the callback function for each NAT entry. + * + * Input Parameters: + * cb - The callback function. + * arg - The argument to pass to the callback function. + * + ****************************************************************************/ + +void ipv4_nat_entry_foreach(ipv4_nat_entry_cb_t cb, FAR void *arg) { FAR hash_node_t *p; FAR hash_node_t *tmp; int i; - ninfo("INFO: Clearing all NAT44 entries for %s\n", dev->d_ifname); - hashtable_for_every_safe(g_nat44_inbound, p, tmp, i) { FAR ipv4_nat_entry_t *entry = container_of(p, ipv4_nat_entry_t, hash_inbound); - if (net_ipv4addr_cmp(entry->external_ip, dev->d_ipaddr)) - { - ipv4_nat_entry_delete(entry); - } + cb(entry, arg); } } diff --git a/net/nat/ipv6_nat_entry.c b/net/nat/ipv6_nat_entry.c index 4ca5d9635b..e4795380a9 100644 --- a/net/nat/ipv6_nat_entry.c +++ b/net/nat/ipv6_nat_entry.c @@ -188,32 +188,25 @@ static void ipv6_nat_entry_delete(FAR ipv6_nat_entry_t *entry) ****************************************************************************/ #if CONFIG_NET_NAT_ENTRY_RECLAIM_SEC > 0 +static void ipv6_nat_reclaim_entry_cb(FAR ipv6_nat_entry_t *entry, + FAR void *arg) +{ + int32_t current_time = *(FAR int32_t *)arg; + + if (entry->expire_time - current_time <= 0) + { + ipv6_nat_entry_delete(entry); + } +} + static void ipv6_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 NAT66 entries.\n"); - - hashtable_for_every_safe(g_nat66_inbound, p, tmp, i) - { - FAR ipv6_nat_entry_t *entry = - container_of(p, ipv6_nat_entry_t, hash_inbound); - - if (entry->expire_time - current_time <= 0) - { - ipv6_nat_entry_delete(entry); - count++; - } - } - - ninfo("INFO: %d expired NAT66 entries reclaimed.\n", count); + ipv6_nat_entry_foreach(ipv6_nat_reclaim_entry_cb, ¤t_time); next_reclaim_time = current_time + CONFIG_NET_NAT_ENTRY_RECLAIM_SEC; } } @@ -221,6 +214,26 @@ static void ipv6_nat_reclaim_entry(int32_t current_time) # define ipv6_nat_reclaim_entry(t) #endif +/**************************************************************************** + * Name: ipv6_nat_entry_clear_cb + * + * Description: + * Clear an entry related to dev. Called when NAT will be disabled on + * any device. + * + ****************************************************************************/ + +static void ipv6_nat_entry_clear_cb(FAR ipv6_nat_entry_t *entry, + FAR void *arg) +{ + FAR struct net_driver_s *dev = arg; + + if (NETDEV_IS_MY_V6ADDR(dev, entry->external_ip)) + { + ipv6_nat_entry_delete(entry); + } +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -241,22 +254,35 @@ static void ipv6_nat_reclaim_entry(int32_t current_time) ****************************************************************************/ void ipv6_nat_entry_clear(FAR struct net_driver_s *dev) +{ + ninfo("INFO: Clearing all NAT66 entries for %s\n", dev->d_ifname); + ipv6_nat_entry_foreach(ipv6_nat_entry_clear_cb, dev); +} + +/**************************************************************************** + * Name: ipv6_nat_entry_foreach + * + * Description: + * Call the callback function for each NAT entry. + * + * Input Parameters: + * cb - The callback function. + * arg - The argument to pass to the callback function. + * + ****************************************************************************/ + +void ipv6_nat_entry_foreach(ipv6_nat_entry_cb_t cb, FAR void *arg) { FAR hash_node_t *p; FAR hash_node_t *tmp; int i; - ninfo("INFO: Clearing all NAT66 entries for %s\n", dev->d_ifname); - hashtable_for_every_safe(g_nat66_inbound, p, tmp, i) { FAR ipv6_nat_entry_t *entry = container_of(p, ipv6_nat_entry_t, hash_inbound); - if (NETDEV_IS_MY_V6ADDR(dev, entry->external_ip)) - { - ipv6_nat_entry_delete(entry); - } + cb(entry, arg); } } diff --git a/net/nat/nat.h b/net/nat/nat.h index cf1ee5b17c..4ef2d40e80 100644 --- a/net/nat/nat.h +++ b/net/nat/nat.h @@ -123,6 +123,11 @@ struct ipv6_nat_entry_s typedef struct ipv4_nat_entry_s ipv4_nat_entry_t; typedef struct ipv6_nat_entry_s ipv6_nat_entry_t; +typedef CODE void (*ipv4_nat_entry_cb_t)(FAR ipv4_nat_entry_t *entry, + FAR void *arg); +typedef CODE void (*ipv6_nat_entry_cb_t)(FAR ipv6_nat_entry_t *entry, + FAR void *arg); + /* NAT IP/Port manipulate type, to indicate whether to manipulate source or * destination IP/Port in a packet. */ @@ -281,6 +286,25 @@ uint16_t nat_port_select(FAR struct net_driver_s *dev, uint32_t nat_expire_time(uint8_t protocol); +/**************************************************************************** + * Name: ipv4/ipv6_nat_entry_foreach + * + * Description: + * Call the callback function for each NAT entry. + * + * Input Parameters: + * cb - The callback function. + * arg - The argument to pass to the callback function. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NAT44 +void ipv4_nat_entry_foreach(ipv4_nat_entry_cb_t cb, FAR void *arg); +#endif +#ifdef CONFIG_NET_NAT66 +void ipv6_nat_entry_foreach(ipv6_nat_entry_cb_t cb, FAR void *arg); +#endif + /**************************************************************************** * Name: ipv4/ipv6_nat_entry_clear *