diff --git a/cmake/FindLibUUID.cmake b/cmake/FindLibUUID.cmake
index d6c4163e96b1e59ce23f87bab6372d5bec4f87c3..0db8ae7e5e155eb0b371a02909566c449b2ff255 100644
--- a/cmake/FindLibUUID.cmake
+++ b/cmake/FindLibUUID.cmake
@@ -3,25 +3,29 @@ if(NOT LIBUUID_FOUND)
         NAMES uuid.h
         PATH_SUFFIXES uuid
     )
-    find_library(LIBUUID_LIBRARIES
-        NAMES uuid
-    )
-
-    if (LIBUUID_INCLUDE_DIR AND LIBUUID_LIBRARIES)
-        set(LIBUUID_FOUND ON)
-    endif(LIBUUID_INCLUDE_DIR AND LIBUUID_LIBRARIES)
-
-    if(LIBUUID_FOUND)
+    if (LIBUUID_INCLUDE_DIR)
         if (NOT LIBUUID_FIND_QUIETLY)
             message(STATUS "Found libuuid includes: ${LIBUUID_INCLUDE_DIR}")
-            message(STATUS "Found libuuid library: ${LIBUUID_LIBRARIES}")
-        endif (NOT LIBUUID_FIND_QUIETLY)
+        endif ()
         set(LIBUUID_INCLUDE_DIRS ${LIBUUID_INCLUDE_DIR})
-    else(LIBUUID_FOUND)
-        if (LIBUUID_FIND_REQUIRED)
-            message(FATAL_ERROR "Could not find libuuid development files")
-        endif (LIBUUID_FIND_REQUIRED)
-    endif(LIBUUID_FOUND)
+        check_library_exists(uuid uuid_is_null "" HAVE_LIBUUID_LINUX)
+        if (HAVE_LIBUUID_LINUX)
+            if (NOT LIBUUID_FIND_QUIETLY)
+                message(STATUS "Found libuuid library: ${LIBUUID_LIBRARIES}")
+            endif ()
+            set(LIBUUID_FOUND ON)
+            set(LIBUUID_LIBRARIES uuid)
+        else()
+            check_library_exists(c uuid_is_nil "" HAVE_LIBUUID_BSD)
+            if (HAVE_LIBUUID_BSD)
+                set(LIBUUID_FOUND ON)
+            elseif (LIBUUID_FIND_REQUIRED)
+                message(FATAL_ERROR "Could not find uuid libraries")
+            endif()
+    endif()
+    elseif(LIBUUID_FIND_REQUIRED)
+         message(FATAL_ERROR "Could not find uuid development files")
+    endif()
 endif (NOT LIBUUID_FOUND)
 
 mark_as_advanced(LIBUUID_LIBRARIES LIBUUID_INCLUDE_DIRS)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index cc437eb7cd6c599b00eaf999f11d87aff280508c..543ac6eddb7e0a7a44c82337c7446497701373cb 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -139,7 +139,7 @@ if (ENABLE_BACKTRACE AND HAVE_BFD)
     endif()
 endif()
 
-set (common_libraries ${common_libraries} uuid)
+set (common_libraries ${common_libraries} ${LIBUUID_LIBRARIES})
 set (common_libraries ${common_libraries} PARENT_SCOPE)
 
 add_subdirectory(lib)
diff --git a/src/replica.cc b/src/replica.cc
index 7ae0355eec27ec570977305672fa95f35a7e5e73..cdd3bb12f9face0cfb5c803d090008d999b706ce 100644
--- a/src/replica.cc
+++ b/src/replica.cc
@@ -154,8 +154,9 @@ replica_bootstrap(struct recovery_state *r, const char *replication_source)
 	char *data = buf;
 	data = mp_encode_map(data, 1);
 	data = mp_encode_uint(data, IPROTO_NODE_UUID);
-	data = mp_encode_str(data, (const char *) &recovery_state->node_uuid,
-			     sizeof(tt_uuid));
+	data = mp_encode_strl(data, UUID_LEN);
+	tt_uuid_enc_be(&recovery_state->node_uuid, data);
+	data += UUID_LEN;
 
 	assert(data <= buf + sizeof(buf));
 	packet.body[0].iov_base = buf;
@@ -212,11 +213,13 @@ remote_connect(struct recovery_state *r, struct ev_io *coio,const char **err)
 	char *data = buf;
 	data = mp_encode_map(data, 3);
 	data = mp_encode_uint(data, IPROTO_CLUSTER_UUID);
-	data = mp_encode_str(data, (const char *) &r->cluster_uuid,
-			     sizeof(tt_uuid));
+	data = mp_encode_strl(data, UUID_LEN);
+	tt_uuid_enc_be(&r->cluster_uuid, data);
+	data += UUID_LEN;
 	data = mp_encode_uint(data, IPROTO_NODE_UUID);
-	data = mp_encode_str(data, (const char *) &r->node_uuid,
-			     sizeof(tt_uuid));
+	data = mp_encode_strl(data, UUID_LEN);
+	tt_uuid_enc_be(&recovery_state->node_uuid, data);
+	data += UUID_LEN;
 	data = mp_encode_uint(data, IPROTO_LSNMAP);
 	data = mp_encode_map(data, cluster_size);
 	uint32_t k;
diff --git a/src/replication.cc b/src/replication.cc
index 5f72b453a4d967041b86135fc4227a27ac36486f..ce303d670704f2f44f53ea6c0eafe861a60fe9e6 100644
--- a/src/replication.cc
+++ b/src/replication.cc
@@ -239,12 +239,12 @@ replication_join(int fd, struct iproto_packet *packet)
 		uint8_t key = mp_decode_uint(&d);
 		if (key == IPROTO_NODE_UUID) {
 			if (mp_typeof(*d) != MP_STR ||
-			    mp_decode_strl(&d) != sizeof(tt_uuid)) {
+			    mp_decode_strl(&d) != UUID_LEN) {
 				tnt_raise(ClientError, ER_INVALID_MSGPACK,
 					  "invalid Node-UUID");
 			}
-			tt_uuid_set(&node_uuid, d);
-			d += sizeof(node_uuid);
+			tt_uuid_dec_be(d, &node_uuid);
+			d += UUID_LEN;
 		} else {
 			mp_next(&d); /* value */
 		}
@@ -302,21 +302,21 @@ replication_subscribe(int fd, struct iproto_packet *packet)
 		switch (key) {
 		case IPROTO_CLUSTER_UUID:
 			if (mp_typeof(*d) != MP_STR ||
-			    mp_decode_strl(&d) != sizeof(cluster_uuid)) {
+			    mp_decode_strl(&d) != UUID_LEN) {
 				tnt_raise(ClientError, ER_INVALID_MSGPACK,
 					  "invalid Cluster-UUID");
 			}
-			tt_uuid_set(&cluster_uuid, d);
-			d += sizeof(cluster_uuid);
+			tt_uuid_dec_be(d, &cluster_uuid);
+			d += UUID_LEN;
 			break;
 		case IPROTO_NODE_UUID:
 			if (mp_typeof(*d) != MP_STR ||
-			    mp_decode_strl(&d) != sizeof(node_uuid)) {
+			    mp_decode_strl(&d) != UUID_LEN) {
 				tnt_raise(ClientError, ER_INVALID_MSGPACK,
 					  "invalid Node-UUID");
 			}
-			tt_uuid_set(&node_uuid, d);
-			d += sizeof(node_uuid);
+			tt_uuid_dec_be(d, &node_uuid);
+			d += UUID_LEN;
 			break;
 		case IPROTO_LSNMAP:
 			if (mp_typeof(*d) != MP_MAP) {
diff --git a/src/trivia/config.h.cmake b/src/trivia/config.h.cmake
index d2d675cb72524c5090aafe46fbbb65940e275b50..9f19173ce843f8a4f80a46b76cf900f42c1dc11a 100644
--- a/src/trivia/config.h.cmake
+++ b/src/trivia/config.h.cmake
@@ -133,6 +133,9 @@
 #cmakedefine HAVE_OPEN_MEMSTREAM 1
 #cmakedefine HAVE_FMEMOPEN 1
 
+#cmakedefine HAVE_LIBUUID_LINUX 1
+#cmakedefine HAVE_LIBUUID_BSD 1
+
 /*
  * predefined /etc directory prefix.
  */
diff --git a/src/tt_uuid.c b/src/tt_uuid.c
index 502809c672b15c0a76fb00b19a7ed7287b712546..6127f5258a0378fe8715d5be4f8f3e18fc24b16f 100644
--- a/src/tt_uuid.c
+++ b/src/tt_uuid.c
@@ -28,10 +28,10 @@
  */
 #include "tt_uuid.h"
 /* Zeroed by the linker. */
-tt_uuid uuid_nil;
+const tt_uuid uuid_nil;
 
 char *
-tt_uuid_str(const struct tt_uuid *uu)
+tt_uuid_str(const tt_uuid *uu)
 {
 	static __thread char buf[UUID_STR_LEN + 1];
 	tt_uuid_to_string(uu, buf);
diff --git a/src/tt_uuid.h b/src/tt_uuid.h
index 2e934ebf25cbba370069770c2468b9b76a6aa6f6..3f584008ce7b97d323727e68f8a5131bdf179773 100644
--- a/src/tt_uuid.h
+++ b/src/tt_uuid.h
@@ -28,22 +28,26 @@
  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include <uuid/uuid.h>
+#include <trivia/config.h>
 #include <string.h>
 #include <stdbool.h>
+#include <stdlib.h>
+#include <assert.h>
 
 #if defined(__cplusplus)
 extern "C" {
 #endif
 
-enum { UUID_STR_LEN = 36 };
+enum { UUID_LEN = 16, UUID_STR_LEN = 36 };
+
+#if defined(HAVE_LIBUUID_LINUX)
+
+#include <uuid/uuid.h>
 
 typedef struct tt_uuid {
 	uuid_t id;
 } tt_uuid;
 
-extern tt_uuid uuid_nil;
-
 static inline void
 tt_uuid_create(tt_uuid *uu)
 {
@@ -63,13 +67,22 @@ tt_uuid_to_string(const tt_uuid *uu, char *out)
 }
 
 static inline void
-tt_uuid_set(tt_uuid *uu, const void *data)
+tt_uuid_dec_be(const void *in, tt_uuid *uu)
 {
-	memcpy(uu->id, data, sizeof(uu->id));
+	memcpy(uu->id, in, sizeof(uu->id));
 }
 
-char *
-tt_uuid_str(const struct tt_uuid *uu);
+static inline void
+tt_uuid_enc_be(const tt_uuid *uu, void *out)
+{
+	memcpy(out, uu->id, sizeof(uu->id));
+}
+
+static inline bool
+tt_uuid_is_nil(const tt_uuid *uu)
+{
+	return uuid_is_null(uu->id);
+}
 
 static inline bool
 tt_uuid_cmp(const tt_uuid *lhs, const tt_uuid *rhs)
@@ -77,12 +90,75 @@ tt_uuid_cmp(const tt_uuid *lhs, const tt_uuid *rhs)
 	return uuid_compare(lhs->id, rhs->id);
 }
 
+#elif defined(HAVE_LIBUUID_BSD)
+
+#include <uuid.h>
+
+typedef struct uuid tt_uuid;
+
+static inline int
+tt_uuid_create(tt_uuid *uu)
+{
+	uint32_t status;
+	uuid_create(uu, &status);
+	return status == uuid_s_ok;
+}
+
+static inline int
+tt_uuid_from_string(const char *in, tt_uuid *uu)
+{
+	uint32_t status;
+	uuid_from_string(in, uu, &status);
+	return status == uuid_s_ok;
+}
+
+static inline void
+tt_uuid_to_string(const tt_uuid *uu, char *out)
+{
+	uint32_t status;
+	char *buf = NULL;
+	uuid_to_string(uu, &buf, &status);
+	assert(status == uuid_s_ok);
+	strncpy(out, buf, UUID_STR_LEN);
+	out[UUID_STR_LEN] = '\0';
+	free(buf);
+}
+
+static inline bool
+tt_uuid_cmp(const tt_uuid *lhs, const tt_uuid *rhs)
+{
+	uint32_t status;
+	return uuid_compare(lhs, rhs, &status);
+}
+
 static inline bool
 tt_uuid_is_nil(const tt_uuid *uu)
 {
-	return uuid_is_null(uu->id);
+	uint32_t status;
+	return uuid_is_nil(uu, &status);
 }
 
+static inline void
+tt_uuid_dec_be(const void *in, tt_uuid *uu)
+{
+	uuid_dec_be(in, uu);
+
+}
+
+static inline void
+tt_uuid_enc_be(const tt_uuid *uu, void *out)
+{
+	uuid_enc_be(out, uu);
+}
+#else
+#error Unsupported libuuid
+#endif /* HAVE_LIBUUID_XXX */
+
+extern const tt_uuid uuid_nil;
+
+char *
+tt_uuid_str(const tt_uuid *uu);
+
 #if defined(__cplusplus)
 } /* extern "C" */
 #endif
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index 41ac98c10eb75e5d59a726a8628d29e3d2913145..e0ba1a678e46d02f543aaadc7fd8e5d4b7f599df 100644
--- a/test/unit/CMakeLists.txt
+++ b/test/unit/CMakeLists.txt
@@ -38,7 +38,7 @@ target_link_libraries(arena_mt.test small pthread)
 add_executable(pt_alloc.test pt_alloc.cc)
 target_link_libraries(pt_alloc.test small)
 add_executable(log_dir.test log_dir.cc test.c)
-target_link_libraries(log_dir.test  uuid core small salad misc bitset msgpuck
+target_link_libraries(log_dir.test ${LIBUUID_LIBRARIES} core small salad misc bitset msgpuck
     ${LIBEV_LIBRARIES}
     ${LIBEIO_LIBRARIES}
     ${LIBCORO_LIBRARIES})