From c742573b67f9b1be953da8f67f417182e7e5dbcb Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Thu, 29 Aug 2019 16:27:00 +0200 Subject: [PATCH] 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 --- bgpd/bgp_bmp.c | 8 +++++++- lib/resolver.c | 14 +++++++++++++- lib/resolver.h | 8 ++++---- nhrpd/nhrp_nhs.c | 4 ++-- tests/lib/test_resolver.c | 2 +- 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; }