aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/nat/nat44-ed/nat44_ed_inlines.h
diff options
context:
space:
mode:
authorAlexander Chernavin <achernavin@netgate.com>2021-05-26 09:55:42 -0400
committerOle Tr�an <otroan@employees.org>2021-06-16 07:58:39 +0000
commitd52a8921b85057682f2cf5bae7d6353142ba279a (patch)
treebce1ea4c27b7106a34d1f316e6975925cbaa2959 /src/plugins/nat/nat44-ed/nat44_ed_inlines.h
parentb862f1dd52b0f5318d67b4463be90562e57f8278 (diff)
nat: test all intf addrs in is_interface_addr()
Type: fix Currently, is_interface_addr() tests if a given IPv4 address belongs to an interface by a given sw_if_index. However, there are several issues: * only the first found address on the interface is actually tested, * sw_if_index is always cached even if the interface hasn't been assigned any addresses yet. With this change, is_interface_addr() tests all IPv4 addresses on an interface by a given sw_if_index and caches sw_if_index only if there are addresses present. Signed-off-by: Alexander Chernavin <achernavin@netgate.com> Change-Id: If1acc4a534647a5f0ce8e9b565b867c92a016dc3
Diffstat (limited to 'src/plugins/nat/nat44-ed/nat44_ed_inlines.h')
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_inlines.h28
1 files changed, 19 insertions, 9 deletions
diff --git a/src/plugins/nat/nat44-ed/nat44_ed_inlines.h b/src/plugins/nat/nat44-ed/nat44_ed_inlines.h
index b2b578a5a8b..680bdef1f9f 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed_inlines.h
+++ b/src/plugins/nat/nat44-ed/nat44_ed_inlines.h
@@ -724,20 +724,30 @@ is_interface_addr (snat_main_t *sm, vlib_node_runtime_t *node,
u32 sw_if_index0, u32 ip4_addr)
{
snat_runtime_t *rt = (snat_runtime_t *) node->runtime_data;
- ip4_address_t *first_int_addr;
+ u8 ip4_addr_exists;
if (PREDICT_FALSE (rt->cached_sw_if_index != sw_if_index0))
{
- first_int_addr = ip4_interface_first_address (
- sm->ip4_main, sw_if_index0, 0 /* just want the address */);
- rt->cached_sw_if_index = sw_if_index0;
- if (first_int_addr)
- rt->cached_ip4_address = first_int_addr->as_u32;
- else
- rt->cached_ip4_address = 0;
+ ip_lookup_main_t *lm = &sm->ip4_main->lookup_main;
+ ip_interface_address_t *ia;
+ ip4_address_t *a;
+
+ rt->cached_sw_if_index = ~0;
+ hash_free (rt->cached_presence_by_ip4_address);
+
+ foreach_ip_interface_address (
+ lm, ia, sw_if_index0, 1 /* honor unnumbered */, ({
+ a = ip_interface_address_get_address (lm, ia);
+ hash_set (rt->cached_presence_by_ip4_address, a->as_u32, 1);
+ rt->cached_sw_if_index = sw_if_index0;
+ }));
+
+ if (rt->cached_sw_if_index == ~0)
+ return 0;
}
- if (PREDICT_FALSE (ip4_addr == rt->cached_ip4_address))
+ ip4_addr_exists = !!hash_get (rt->cached_presence_by_ip4_address, ip4_addr);
+ if (PREDICT_FALSE (ip4_addr_exists))
return 1;
else
return 0;