diff options
Diffstat (limited to 'src/plugins/dns/dns.c')
-rw-r--r-- | src/plugins/dns/dns.c | 231 |
1 files changed, 39 insertions, 192 deletions
diff --git a/src/plugins/dns/dns.c b/src/plugins/dns/dns.c index 0801681b8b3..3cecf942d55 100644 --- a/src/plugins/dns/dns.c +++ b/src/plugins/dns/dns.c @@ -16,9 +16,8 @@ #include <vnet/vnet.h> #include <vnet/udp/udp_local.h> #include <vnet/plugin/plugin.h> -#include <vnet/fib/fib_table.h> #include <dns/dns.h> - +#include <vnet/ip/ip_sas.h> #include <vlibapi/api.h> #include <vlibmemory/api.h> #include <vpp/app/version.h> @@ -31,16 +30,27 @@ #define REPLY_MSG_ID_BASE dm->msg_id_base #include <vlibapi/api_helper_macros.h> -/* Macro to finish up custom dump fns */ -#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) -#define FINISH \ - vec_add1 (s, 0); \ - vl_print (handle, (char *)s); \ - vec_free (s); \ - return handle; +#define FINISH \ + vec_add1 (s, 0); \ + vlib_cli_output (handle, (char *) s); \ + vec_free (s); \ + return handle; dns_main_t dns_main; +/* the cache hashtable expects a NULL-terminated C-string but everywhere else + * expects a non-NULL terminated vector... The pattern of adding \0 but hiding + * it away drives AddressSanitizer crazy, this helper tries to bring some of + * its sanity back + */ +static_always_inline void +dns_terminate_c_string (u8 **v) +{ + vec_add1 (*v, 0); + vec_dec_len (*v, 1); + clib_mem_unpoison (vec_end (*v), 1); +} + static int dns_cache_clear (dns_main_t * dm) { @@ -51,13 +61,11 @@ dns_cache_clear (dns_main_t * dm) dns_cache_lock (dm, 1); - /* *INDENT-OFF* */ pool_foreach (ep, dm->entries) { vec_free (ep->name); vec_free (ep->pending_requests); } - /* *INDENT-ON* */ pool_free (dm->entries); hash_free (dm->cache_entry_by_name); @@ -225,66 +233,16 @@ vnet_dns_send_dns4_request (vlib_main_t * vm, dns_main_t * dm, u32 bi; vlib_buffer_t *b; ip4_header_t *ip; - fib_prefix_t prefix; - fib_node_index_t fei; - u32 sw_if_index, fib_index; udp_header_t *udp; - ip4_main_t *im4 = &ip4_main; - ip_lookup_main_t *lm4 = &im4->lookup_main; - ip_interface_address_t *ia = 0; - ip4_address_t *src_address; + ip4_address_t src_address; u8 *dns_request; vlib_frame_t *f; u32 *to_next; ASSERT (ep->dns_request); - /* Find a FIB path to the server */ - clib_memcpy (&prefix.fp_addr.ip4, server, sizeof (*server)); - prefix.fp_proto = FIB_PROTOCOL_IP4; - prefix.fp_len = 32; - - fib_index = fib_table_find (prefix.fp_proto, 0 /* default VRF for now */ ); - if (fib_index == (u32) ~ 0) - { - if (0) - clib_warning ("no fib table"); - return; - } - - fei = fib_table_lookup (fib_index, &prefix); - - /* Couldn't find route to destination. Bail out. */ - if (fei == FIB_NODE_INDEX_INVALID) - { - if (0) - clib_warning ("no route to DNS server"); - return; - } - - sw_if_index = fib_entry_get_resolving_interface (fei); - - if (sw_if_index == ~0) - { - if (0) - clib_warning - ("route to %U exists, fei %d, get_resolving_interface returned" - " ~0", format_ip4_address, &prefix.fp_addr, fei); - return; - } - - /* *INDENT-OFF* */ - foreach_ip_interface_address(lm4, ia, sw_if_index, 1 /* honor unnumbered */, - ({ - src_address = ip_interface_address_get_address (lm4, ia); - goto found_src_address; - })); - /* *INDENT-ON* */ - - clib_warning ("FIB BUG"); - return; - -found_src_address: + if (!ip4_sas (0 /* default VRF for now */, ~0, server, &src_address)) + return; /* Go get a buffer */ if (vlib_buffer_alloc (vm, &bi, 1) != 1) @@ -311,7 +269,7 @@ found_src_address: ip->length = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b)); ip->ttl = 255; ip->protocol = IP_PROTOCOL_UDP; - ip->src_address.as_u32 = src_address->as_u32; + ip->src_address.as_u32 = src_address.as_u32; ip->dst_address.as_u32 = server->as_u32; ip->checksum = ip4_header_checksum (ip); @@ -343,14 +301,8 @@ vnet_dns_send_dns6_request (vlib_main_t * vm, dns_main_t * dm, u32 bi; vlib_buffer_t *b; ip6_header_t *ip; - fib_prefix_t prefix; - fib_node_index_t fei; - u32 sw_if_index, fib_index; udp_header_t *udp; - ip6_main_t *im6 = &ip6_main; - ip_lookup_main_t *lm6 = &im6->lookup_main; - ip_interface_address_t *ia = 0; - ip6_address_t *src_address; + ip6_address_t src_address; u8 *dns_request; vlib_frame_t *f; u32 *to_next; @@ -358,41 +310,8 @@ vnet_dns_send_dns6_request (vlib_main_t * vm, dns_main_t * dm, ASSERT (ep->dns_request); - /* Find a FIB path to the server */ - clib_memcpy (&prefix.fp_addr, server, sizeof (*server)); - prefix.fp_proto = FIB_PROTOCOL_IP6; - prefix.fp_len = 32; - - fib_index = fib_table_find (prefix.fp_proto, 0 /* default VRF for now */ ); - if (fib_index == (u32) ~ 0) - { - if (0) - clib_warning ("no fib table"); - return; - } - - fei = fib_table_lookup (fib_index, &prefix); - - /* Couldn't find route to destination. Bail out. */ - if (fei == FIB_NODE_INDEX_INVALID) - { - clib_warning ("no route to DNS server"); - } - - sw_if_index = fib_entry_get_resolving_interface (fei); - - /* *INDENT-OFF* */ - foreach_ip_interface_address(lm6, ia, sw_if_index, 1 /* honor unnumbered */, - ({ - src_address = ip_interface_address_get_address (lm6, ia); - goto found_src_address; - })); - /* *INDENT-ON* */ - - clib_warning ("FIB BUG"); - return; - -found_src_address: + if (!ip6_sas (0 /* default VRF for now */, ~0, server, &src_address)) + return; /* Go get a buffer */ if (vlib_buffer_alloc (vm, &bi, 1) != 1) @@ -421,7 +340,7 @@ found_src_address: - sizeof (ip6_header_t)); ip->hop_limit = 255; ip->protocol = IP_PROTOCOL_UDP; - clib_memcpy (&ip->src_address, src_address, sizeof (ip6_address_t)); + ip6_address_copy (&ip->src_address, &src_address); clib_memcpy (&ip->dst_address, server, sizeof (ip6_address_t)); /* UDP header */ @@ -918,8 +837,8 @@ re_resolve: pool_get (dm->entries, ep); clib_memset (ep, 0, sizeof (*ep)); - ep->name = format (0, "%s%c", name, 0); - _vec_len (ep->name) = vec_len (ep->name) - 1; + ep->name = format (0, "%s", name); + dns_terminate_c_string (&ep->name); hash_set_mem (dm->cache_entry_by_name, ep->name, ep - dm->entries); @@ -1077,8 +996,7 @@ found_last_request: now = vlib_time_now (vm); cname = vnet_dns_labels_to_name (rr->rdata, reply, &pos2); /* Save the cname */ - vec_add1 (cname, 0); - _vec_len (cname) -= 1; + dns_terminate_c_string (&cname); ep = pool_elt_at_index (dm->entries, ep_index); ep->cname = cname; ep->flags |= (DNS_CACHE_ENTRY_FLAG_CNAME | DNS_CACHE_ENTRY_FLAG_VALID); @@ -1096,8 +1014,7 @@ found_last_request: clib_memset (next_ep, 0, sizeof (*next_ep)); next_ep->name = vec_dup (cname); - vec_add1 (next_ep->name, 0); - _vec_len (next_ep->name) -= 1; + dns_terminate_c_string (&next_ep->name); hash_set_mem (dm->cache_entry_by_name, next_ep->name, next_ep - dm->entries); @@ -1460,7 +1377,7 @@ vl_api_dns_resolve_name_t_handler (vl_api_dns_resolve_name_t * mp) dns_main_t *dm = &dns_main; vl_api_dns_resolve_name_reply_t *rmp; dns_cache_entry_t *ep = 0; - dns_pending_request_t _t0, *t0 = &_t0; + dns_pending_request_t _t0 = { 0 }, *t0 = &_t0; int rv; dns_resolve_name_t rn; @@ -1484,7 +1401,6 @@ vl_api_dns_resolve_name_t_handler (vl_api_dns_resolve_name_t * mp) if (ep == 0) return; - /* *INDENT-OFF* */ REPLY_MACRO2 (VL_API_DNS_RESOLVE_NAME_REPLY, ({ ip_address_copy_addr (rmp->ip4_address, &rn.address); if (ip_addr_version (&rn.address) == AF_IP4) @@ -1492,7 +1408,6 @@ vl_api_dns_resolve_name_t_handler (vl_api_dns_resolve_name_t * mp) else rmp->ip6_set = 1; })); - /* *INDENT-ON* */ } static void @@ -1506,7 +1421,7 @@ vl_api_dns_resolve_ip_t_handler (vl_api_dns_resolve_ip_t * mp) int i, len; u8 *lookup_name = 0; u8 digit, nybble; - dns_pending_request_t _t0, *t0 = &_t0; + dns_pending_request_t _t0 = { 0 }, *t0 = &_t0; if (mp->is_ip6) { @@ -1561,13 +1476,11 @@ vl_api_dns_resolve_ip_t_handler (vl_api_dns_resolve_ip_t * mp) if (ep == 0) return; - /* *INDENT-OFF* */ REPLY_MACRO2(VL_API_DNS_RESOLVE_IP_REPLY, ({ rv = vnet_dns_response_to_name (ep->dns_response, rmp, 0 /* ttl-ptr */); rmp->retval = clib_host_to_net_u32 (rv); })); - /* *INDENT-ON* */ } static clib_error_t * @@ -2177,7 +2090,6 @@ format_dns_cache (u8 * s, va_list * args) if (verbose > 0) { - /* *INDENT-OFF* */ pool_foreach (ep, dm->entries) { if (ep->flags & DNS_CACHE_ENTRY_FLAG_VALID) @@ -2216,7 +2128,6 @@ format_dns_cache (u8 * s, va_list * args) } vec_add1 (s, '\n'); } - /* *INDENT-ON* */ } dns_cache_unlock (dm); @@ -2251,14 +2162,12 @@ show_dns_cache_command_fn (vlib_main_t * vm, return 0; } -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (show_dns_cache_command) = { .path = "show dns cache", .short_help = "show dns cache [verbose [nn]]", .function = show_dns_cache_command_fn, }; -/* *INDENT-ON* */ static clib_error_t * show_dns_servers_command_fn (vlib_main_t * vm, @@ -2288,14 +2197,12 @@ show_dns_servers_command_fn (vlib_main_t * vm, return 0; } -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (show_dns_server_command) = { .path = "show dns servers", .short_help = "show dns servers", .function = show_dns_servers_command_fn, }; -/* *INDENT-ON* */ static clib_error_t * @@ -2390,14 +2297,12 @@ dns_cache_add_del_command_fn (vlib_main_t * vm, return 0; } -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (dns_cache_add_del_command) = { .path = "dns cache", .short_help = "dns cache [add|del|clear] <name> [ip4][ip6]", .function = dns_cache_add_del_command_fn, }; -/* *INDENT-ON* */ #define DNS_FORMAT_TEST 1 @@ -2638,14 +2543,12 @@ test_dns_fmt_command_fn (vlib_main_t * vm, } -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (test_dns_fmt_command) = { .path = "test dns format", .short_help = "test dns format", .function = test_dns_fmt_command_fn, }; -/* *INDENT-ON* */ static clib_error_t * test_dns_unfmt_command_fn (vlib_main_t * vm, @@ -2678,14 +2581,12 @@ test_dns_unfmt_command_fn (vlib_main_t * vm, return 0; } -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (test_dns_unfmt_command) = { .path = "test dns unformat", .short_help = "test dns unformat <name> [ip4][ip6]", .function = test_dns_unfmt_command_fn, }; -/* *INDENT-ON* */ static clib_error_t * test_dns_expire_command_fn (vlib_main_t * vm, @@ -2699,10 +2600,7 @@ test_dns_expire_command_fn (vlib_main_t * vm, dns_cache_entry_t *ep; if (unformat (input, "%v", &name)) - { - vec_add1 (name, 0); - _vec_len (name) -= 1; - } + dns_terminate_c_string (&name); else return clib_error_return (0, "no name provided"); @@ -2724,14 +2622,12 @@ test_dns_expire_command_fn (vlib_main_t * vm, return 0; } -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (test_dns_expire_command) = { .path = "test dns expire", .short_help = "test dns expire <name>", .function = test_dns_expire_command_fn, }; -/* *INDENT-ON* */ #endif void @@ -2749,13 +2645,7 @@ vnet_send_dns4_reply (vlib_main_t * vm, dns_main_t * dm, vlib_buffer_t * b0) { u32 bi = 0; - fib_prefix_t prefix; - fib_node_index_t fei; - u32 sw_if_index, fib_index; - ip4_main_t *im4 = &ip4_main; - ip_lookup_main_t *lm4 = &im4->lookup_main; - ip_interface_address_t *ia = 0; - ip4_address_t *src_address; + ip4_address_t src_address; ip4_header_t *ip; udp_header_t *udp; dns_header_t *dh; @@ -2839,50 +2729,9 @@ vnet_send_dns4_reply (vlib_main_t * vm, dns_main_t * dm, vnet_buffer (b0)->sw_if_index[VLIB_RX] = 0; /* "local0" */ vnet_buffer (b0)->sw_if_index[VLIB_TX] = 0; /* default VRF for now */ - /* Find a FIB path to the peer we're trying to answer */ - clib_memcpy (&prefix.fp_addr.ip4, pr->dst_address, sizeof (ip4_address_t)); - prefix.fp_proto = FIB_PROTOCOL_IP4; - prefix.fp_len = 32; - - fib_index = fib_table_find (prefix.fp_proto, 0 /* default VRF for now */ ); - if (fib_index == (u32) ~ 0) - { - clib_warning ("no fib table"); - return; - } - - fei = fib_table_lookup (fib_index, &prefix); - - /* Couldn't find route to destination. Bail out. */ - if (fei == FIB_NODE_INDEX_INVALID) - { - clib_warning ("no route to DNS server"); - return; - } - - sw_if_index = fib_entry_get_resolving_interface (fei); - - if (sw_if_index == ~0) - { - clib_warning ( - "route to %U exists, fei %d, get_resolving_interface returned" - " ~0", - format_ip4_address, &prefix.fp_addr, fei); - return; - } - - /* *INDENT-OFF* */ - foreach_ip_interface_address(lm4, ia, sw_if_index, 1 /* honor unnumbered */, - ({ - src_address = ip_interface_address_get_address (lm4, ia); - goto found_src_address; - })); - /* *INDENT-ON* */ - - clib_warning ("FIB BUG"); - return; - -found_src_address: + if (!ip4_sas (0 /* default VRF for now */, ~0, + (const ip4_address_t *) &pr->dst_address, &src_address)) + return; ip = vlib_buffer_get_current (b0); udp = (udp_header_t *) (ip + 1); @@ -2975,7 +2824,7 @@ found_src_address: ip->length = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0)); ip->ttl = 255; ip->protocol = IP_PROTOCOL_UDP; - ip->src_address.as_u32 = src_address->as_u32; + ip->src_address.as_u32 = src_address.as_u32; clib_memcpy (ip->dst_address.as_u8, pr->dst_address, sizeof (ip4_address_t)); ip->checksum = ip4_header_checksum (ip); @@ -3020,7 +2869,6 @@ dns_init (vlib_main_t * vm) return 0; } -/* *INDENT-OFF* */ VLIB_INIT_FUNCTION (dns_init) = { .init_order = VLIB_INITS ("flow_classify_init", "dns_init"), }; @@ -3030,7 +2878,6 @@ VLIB_PLUGIN_REGISTER () = .version = VPP_BUILD_VER, .description = "Simple DNS name resolver", }; -/* *INDENT-ON* */ /* |