summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2019-08-29 16:27:00 +0200
committerPhilippe Guibert <philippe.guibert@6wind.com>2021-11-23 09:02:23 +0100
commitc742573b67f9b1be953da8f67f417182e7e5dbcb (patch)
treeef43653783f7113fbcbdfeeadf9d3bae09f39aec
parent56cc2c987d323b97a2229d536fbc8ef88dd6bfc7 (diff)
lib: resolver per vrf support
add a parameter to resolver api that is the vrf identifier. this permits to make resolution self to each vrf. in case vrf netns backend is used, this is very practical, since resolution can happen on one netns, while it is not the case in an other one. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
-rw-r--r--bgpd/bgp_bmp.c8
-rw-r--r--lib/resolver.c14
-rw-r--r--lib/resolver.h8
-rw-r--r--nhrpd/nhrp_nhs.c4
-rw-r--r--tests/lib/test_resolver.c2
5 files changed, 27 insertions, 9 deletions
diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c
index 1bc3fd0dba..b4da226999 100644
--- a/bgpd/bgp_bmp.c
+++ b/bgpd/bgp_bmp.c
@@ -1833,6 +1833,7 @@ static int bmp_active_thread(struct thread *t)
socklen_t slen;
int status, ret;
char buf[SU_ADDRSTRLEN];
+ vrf_id_t vrf_id;
/* all 3 end up here, though only timer or read+write are active
* at a time */
@@ -1843,7 +1844,12 @@ static int bmp_active_thread(struct thread *t)
ba->last_err = NULL;
if (ba->socket == -1) {
- resolver_resolve(&ba->resq, AF_UNSPEC, ba->hostname,
+ /* get vrf_id */
+ if (!ba->targets || !ba->targets->bgp)
+ vrf_id = VRF_DEFAULT;
+ else
+ vrf_id = ba->targets->bgp->vrf_id;
+ resolver_resolve(&ba->resq, AF_UNSPEC, vrf_id, ba->hostname,
bmp_active_resolved);
return 0;
}
diff --git a/lib/resolver.c b/lib/resolver.c
index e3dba5f8ae..29138bbc8d 100644
--- a/lib/resolver.c
+++ b/lib/resolver.c
@@ -21,6 +21,7 @@
#include "resolver.h"
#include "command.h"
#include "xref.h"
+#include "vrf.h"
XREF_SETUP();
@@ -244,7 +245,7 @@ static int resolver_cb_literal(struct thread *t)
return 0;
}
-void resolver_resolve(struct resolver_query *query, int af,
+void resolver_resolve(struct resolver_query *query, int af, vrf_id_t vrf_id,
const char *hostname,
void (*callback)(struct resolver_query *, const char *,
int, union sockunion *))
@@ -279,7 +280,18 @@ void resolver_resolve(struct resolver_query *query, int af,
if (resolver_debug)
zlog_debug("[%p] Resolving '%s'", query, hostname);
+ ret = vrf_switch_to_netns(vrf_id);
+ if (ret < 0) {
+ flog_err_sys(EC_LIB_SOCKET, "%s: Can't switch to VRF %u (%s)",
+ __func__, vrf_id, safe_strerror(errno));
+ return;
+ }
ares_gethostbyname(state.channel, hostname, af, ares_address_cb, query);
+ ret = vrf_switchback_to_initial();
+ if (ret < 0)
+ flog_err_sys(EC_LIB_SOCKET,
+ "%s: Can't switchback from VRF %u (%s)", __func__,
+ vrf_id, safe_strerror(errno));
resolver_update_timeouts(&state);
}
diff --git a/lib/resolver.h b/lib/resolver.h
index 5f922dcb57..988449693c 100644
--- a/lib/resolver.h
+++ b/lib/resolver.h
@@ -27,10 +27,10 @@ struct resolver_query {
};
void resolver_init(struct thread_master *tm);
-void resolver_resolve(struct resolver_query *query, int af,
- const char *hostname, void (*cb)(struct resolver_query *,
- const char *, int,
- union sockunion *));
+void resolver_resolve(struct resolver_query *query, int af, vrf_id_t vrf_id,
+ const char *hostname,
+ void (*cb)(struct resolver_query *, const char *, int,
+ union sockunion *));
#ifdef __cplusplus
}
diff --git a/nhrpd/nhrp_nhs.c b/nhrpd/nhrp_nhs.c
index 597c125e17..3733910a63 100644
--- a/nhrpd/nhrp_nhs.c
+++ b/nhrpd/nhrp_nhs.c
@@ -324,8 +324,8 @@ static int nhrp_nhs_resolve(struct thread *t)
{
struct nhrp_nhs *nhs = THREAD_ARG(t);
- resolver_resolve(&nhs->dns_resolve, AF_INET, nhs->nbma_fqdn,
- nhrp_nhs_resolve_cb);
+ resolver_resolve(&nhs->dns_resolve, AF_INET, VRF_DEFAULT,
+ nhs->nbma_fqdn, nhrp_nhs_resolve_cb);
return 0;
}
diff --git a/tests/lib/test_resolver.c b/tests/lib/test_resolver.c
index 0b3dccc820..6a582cceaf 100644
--- a/tests/lib/test_resolver.c
+++ b/tests/lib/test_resolver.c
@@ -63,7 +63,7 @@ DEFUN (test_resolve,
"DNS resolver\n"
"Name to resolve\n")
{
- resolver_resolve(&query, AF_UNSPEC, argv[1]->arg, resolver_result);
+ resolver_resolve(&query, AF_UNSPEC, 0, argv[1]->arg, resolver_result);
return CMD_SUCCESS;
}