Merge RP1A.200123.001

Change-Id: I200bc23e592940e29ff82709e73113ebb286a5d6
diff --git a/Android.bp b/Android.bp
index 2f657d1..7034daf 100644
--- a/Android.bp
+++ b/Android.bp
@@ -245,6 +245,23 @@
 }
 
 cc_library_static {
+    name: "libgrpc_transport_chttp2_server_secure",
+    defaults: ["grpc_defaults"],
+    srcs: [
+        "src/core/ext/transport/chttp2/server/chttp2_server.cc",
+        "src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc",
+    ],
+    local_include_dirs: [
+        "include",
+    ],
+    static_libs: [
+        "libgrpc_base",
+        "libgrpc_transport_chttp2",
+        "libprotobuf-c-nano",
+    ],
+}
+
+cc_library_static {
     name: "libgrpc_transport_chttp2_client_insecure",
     defaults: ["grpc_defaults"],
     srcs: [
@@ -265,6 +282,25 @@
 }
 
 cc_library_static {
+    name: "libgrpc_transport_chttp2_client_secure",
+    defaults: ["grpc_defaults"],
+    srcs: [
+        "src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc",
+    ],
+    local_include_dirs: [
+        "include",
+    ],
+    static_libs: [
+        "libgrpc_base",
+        "libgrpc_client_channel",
+        "libgrpc_deadline_filter",
+        "libgrpc_transport_chttp2",
+        "libgrpc_transport_chttp2_client_connector",
+        "libprotobuf-c-nano",
+    ],
+}
+
+cc_library_static {
     name: "libgrpc_message_size_filter",
     defaults: ["grpc_defaults"],
     srcs: [
@@ -355,6 +391,170 @@
 }
 
 cc_library_static {
+    name: "libgrpc_secure",
+    defaults: ["grpc_defaults"],
+    srcs: [
+        "src/core/lib/http/httpcli_security_connector.cc",
+        "src/core/lib/security/context/security_context.cc",
+        "src/core/lib/security/credentials/alts/alts_credentials.cc",
+        "src/core/lib/security/credentials/composite/composite_credentials.cc",
+        "src/core/lib/security/credentials/credentials.cc",
+        "src/core/lib/security/credentials/credentials_metadata.cc",
+        "src/core/lib/security/credentials/fake/fake_credentials.cc",
+        "src/core/lib/security/credentials/google_default/credentials_generic.cc",
+        "src/core/lib/security/credentials/google_default/google_default_credentials.cc",
+        "src/core/lib/security/credentials/iam/iam_credentials.cc",
+        "src/core/lib/security/credentials/jwt/json_token.cc",
+        "src/core/lib/security/credentials/jwt/jwt_credentials.cc",
+        "src/core/lib/security/credentials/jwt/jwt_verifier.cc",
+        "src/core/lib/security/credentials/local/local_credentials.cc",
+        "src/core/lib/security/credentials/oauth2/oauth2_credentials.cc",
+        "src/core/lib/security/credentials/plugin/plugin_credentials.cc",
+        "src/core/lib/security/credentials/ssl/ssl_credentials.cc",
+        "src/core/lib/security/security_connector/alts_security_connector.cc",
+        "src/core/lib/security/security_connector/load_system_roots_fallback.cc",
+        "src/core/lib/security/security_connector/load_system_roots_linux.cc",
+        "src/core/lib/security/security_connector/local_security_connector.cc",
+        "src/core/lib/security/security_connector/security_connector.cc",
+        "src/core/lib/security/transport/client_auth_filter.cc",
+        "src/core/lib/security/transport/secure_endpoint.cc",
+        "src/core/lib/security/transport/security_handshaker.cc",
+        "src/core/lib/security/transport/server_auth_filter.cc",
+        "src/core/lib/security/transport/target_authority_table.cc",
+        "src/core/lib/security/transport/tsi_error.cc",
+        "src/core/lib/security/util/json_util.cc",
+        "src/core/lib/surface/init_secure.cc",
+    ],
+    local_include_dirs: [
+        "include",
+        "third_party/nanopb",
+    ],
+    static_libs: [
+        "libgrpc_base",
+        "libgrpc_transport_chttp2_alpn",
+    ],
+    whole_static_libs: [
+        "libalts_frame_protector",
+        "libtsi",
+    ],
+    shared_libs: [
+        "libcrypto",
+        "libssl",
+    ],
+}
+
+cc_library_static {
+    name: "libalts_util",
+    defaults: ["grpc_defaults"],
+    srcs: [
+        "src/core/lib/security/credentials/alts/check_gcp_environment.cc",
+        "src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc",
+        "src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc",
+        "src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc",
+        "src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc",
+        "src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc",
+        "src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc",
+        "src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc",
+        "src/core/tsi/alts/handshaker/altscontext.pb.c",
+        "src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.cc",
+        "src/core/tsi/alts/handshaker/handshaker.pb.c",
+        "src/core/tsi/alts/handshaker/transport_security_common_api.cc",
+        "src/core/tsi/alts/handshaker/transport_security_common.pb.c",
+    ],
+    local_include_dirs: [
+        "include",
+    ],
+    static_libs: [
+        "libprotobuf-c-nano",
+    ],
+    cflags: [
+        "-DPB_FIELD_16BIT",
+    ],
+}
+
+cc_library_static {
+    name: "libtsi",
+    defaults: ["grpc_defaults"],
+    srcs: [
+        "src/core/tsi/alts/handshaker/alts_handshaker_client.cc",
+        "src/core/tsi/alts/handshaker/alts_tsi_event.cc",
+        "src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc",
+        "src/core/tsi/alts/handshaker/alts_tsi_utils.cc",
+        "src/core/tsi/alts_transport_security.cc",
+        "src/core/tsi/fake_transport_security.cc",
+        "src/core/tsi/local_transport_security.cc",
+        "src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc",
+        "src/core/tsi/ssl/session_cache/ssl_session_cache.cc",
+        "src/core/tsi/ssl/session_cache/ssl_session_openssl.cc",
+        "src/core/tsi/ssl_transport_security.cc",
+        "src/core/tsi/transport_security_grpc.cc",
+    ],
+    local_include_dirs: [
+        "include",
+        "third_party/nanopb",
+    ],
+    static_libs: [
+        "libalts_frame_protector",
+        "gpr_base",
+        "libgrpc_base",
+        "libgrpc_transport_chttp2_client_insecure",
+    ],
+    whole_static_libs: [
+        "libalts_util",
+    ],
+    shared_libs: [
+        "libcrypto",
+        "libssl",
+    ],
+}
+
+cc_library_static {
+    name: "libalts_frame_protector",
+    defaults: ["grpc_defaults"],
+    srcs: [
+        "src/core/tsi/alts/crypt/aes_gcm.cc",
+        "src/core/tsi/alts/crypt/gsec.cc",
+        "src/core/tsi/alts/frame_protector/alts_counter.cc",
+        "src/core/tsi/alts/frame_protector/alts_crypter.cc",
+        "src/core/tsi/alts/frame_protector/alts_frame_protector.cc",
+        "src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.cc",
+        "src/core/tsi/alts/frame_protector/alts_seal_privacy_integrity_crypter.cc",
+        "src/core/tsi/alts/frame_protector/alts_unseal_privacy_integrity_crypter.cc",
+        "src/core/tsi/alts/frame_protector/frame_handler.cc",
+        "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc",
+        "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc",
+        "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc",
+        "src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc",
+        "src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc",
+    ],
+    local_include_dirs: [
+        "include",
+    ],
+    static_libs: [
+        "gpr_base",
+        "libgrpc_base",
+    ],
+    whole_static_libs: [
+        "libtsi_interface",
+    ],
+    shared_libs: [
+        "libcrypto",
+        "libssl",
+    ],
+}
+
+cc_library_static {
+    name: "libtsi_interface",
+    defaults: ["grpc_defaults"],
+    srcs: [
+        "src/core/tsi/transport_security.cc",
+    ],
+    static_libs: [
+        "libgrpc_trace",
+    ],
+}
+
+cc_library_static {
     name: "libgrpc_transport_chttp2",
     defaults: ["grpc_defaults"],
     srcs: [
@@ -388,6 +588,8 @@
     static_libs: [
         "libgrpc_base",
         "libgrpc_http_filters",
+    ],
+    whole_static_libs: [
         "libgrpc_transport_chttp2_alpn",
     ],
 }
@@ -419,6 +621,32 @@
 }
 
 cc_library_static {
+    name: "libgrpc_lb_policy_grpclb_secure",
+    defaults: ["grpc_defaults"],
+    srcs: [
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
+    ],
+    local_include_dirs: [
+        "include",
+        "src/core/ext/filters/client_channel/lb_policy/grpclb",
+    ],
+    static_libs: [
+        "libgrpc_base",
+        "libgrpc_client_channel",
+        "libgrpc_deadline_filter",
+        "libgrpc_resolver_fake",
+        "libprotobuf-c-nano",
+    ],
+}
+
+cc_library_static {
     name: "libgrpc++_codegen_base_src",
     defaults: ["grpc_defaults"],
     srcs: [
@@ -525,7 +753,7 @@
     srcs: [
         "src/core/lib/debug/trace.cc",
     ],
-    static_libs: [
+    whole_static_libs: [
         "gpr_base",
     ],
     shared_libs: [
@@ -686,9 +914,8 @@
         "src/core/lib/transport/transport.cc",
         "src/core/lib/transport/transport_op_string.cc",
     ],
-    static_libs: [
+    whole_static_libs: [
         "libgrpc_trace",
-        "gpr_base",
         "libz",
     ],
     shared_libs: [
@@ -710,6 +937,32 @@
     ],
 }
 
+grpc_common_libs = [
+    "libgrpc_base",
+    "census",
+    "libgrpc_base_c",
+    "libgrpc_deadline_filter",
+    "libgrpc_client_authority_filter",
+    "libgrpc_client_channel",
+    "libgrpc_lb_policy_pick_first",
+    "libgrpc_lb_policy_round_robin",
+    "libgrpc_max_age_filter",
+    "libgrpc_message_size_filter",
+    "libgrpc_resolver_dns_ares",
+    "libgrpc_resolver_fake",
+    "libgrpc_resolver_dns_native",
+    "libgrpc_resolver_sockaddr",
+    "libgrpc_transport_chttp2_server_insecure",
+    "libgrpc_transport_chttp2_client_insecure",
+    "libgrpc_http_filters",
+    "libgrpc_transport_chttp2",
+    "libgrpc_transport_chttp2_client_connector",
+    "libgrpc_transport_inproc",
+    "libgrpc_workaround_cronet_compression_filter",
+    "libgrpc_server_backward_compatibility",
+    "libprotobuf-c-nano",
+]
+
 cc_library_static {
     name: "libgrpc_unsecure",
     defaults: ["grpc_defaults"],
@@ -718,30 +971,8 @@
         "src/core/lib/surface/init_unsecure.cc",
         "src/core/plugin_registry/grpc_unsecure_plugin_registry.cc",
     ],
-    static_libs: [
-        "libgrpc_base",
-        "libgrpc_client_channel",
-        "libgrpc_client_authority_filter",
-        "libgrpc_deadline_filter",
-        "libgrpc_resolver_dns_native",
-        "libgrpc_http_filters",
+    whole_static_libs: grpc_common_libs + [
         "libgrpc_lb_policy_grpclb",
-        "libgrpc_lb_policy_pick_first",
-        "libgrpc_lb_policy_round_robin",
-        "libgrpc_max_age_filter",
-        "libgrpc_message_size_filter",
-        "libgrpc_resolver_dns_ares",
-        "libgrpc_resolver_dns_native",
-        "libgrpc_resolver_fake",
-        "libgrpc_resolver_sockaddr",
-        "libgrpc_server_backward_compatibility",
-        "libgrpc_transport_chttp2",
-        "libgrpc_transport_chttp2_server_insecure",
-        "libgrpc_transport_chttp2_client_insecure",
-        "libgrpc_transport_inproc",
-        "libgrpc_trace",
-        "libgrpc_workaround_cronet_compression_filter",
-        "libprotobuf-c-nano",
     ],
     export_include_dirs: [
         "include",
@@ -754,73 +985,94 @@
 }
 
 cc_library_static {
-    name: "libgrpc++_base",
+    name: "libgrpc",
     defaults: ["grpc_defaults"],
     srcs: [
-        "src/cpp/client/channel_cc.cc",
-        "src/cpp/client/client_context.cc",
-        "src/cpp/client/create_channel.cc",
-        "src/cpp/client/create_channel_internal.cc",
-        "src/cpp/client/create_channel_posix.cc",
-        "src/cpp/client/credentials_cc.cc",
-        "src/cpp/client/generic_stub.cc",
-        "src/cpp/common/alarm.cc",
-        "src/cpp/common/channel_arguments.cc",
-        "src/cpp/common/channel_filter.cc",
-        "src/cpp/common/completion_queue_cc.cc",
-        "src/cpp/common/core_codegen.cc",
-        "src/cpp/common/resource_quota_cc.cc",
-        "src/cpp/common/rpc_method.cc",
-        "src/cpp/common/version_cc.cc",
-        "src/cpp/server/async_generic_service.cc",
-        "src/cpp/server/channel_argument_option.cc",
-        "src/cpp/server/create_default_thread_pool.cc",
-        "src/cpp/server/dynamic_thread_pool.cc",
-        "src/cpp/server/health/default_health_check_service.cc",
-        "src/cpp/server/health/health.pb.c",
-        "src/cpp/server/health/health_check_service.cc",
-        "src/cpp/server/health/health_check_service_server_builder_option.cc",
-        "src/cpp/server/server_builder.cc",
-        "src/cpp/server/server_cc.cc",
-        "src/cpp/server/server_context.cc",
-        "src/cpp/server/server_credentials.cc",
-        "src/cpp/server/server_posix.cc",
-        "src/cpp/thread_manager/thread_manager.cc",
-        "src/cpp/util/byte_buffer_cc.cc",
-        "src/cpp/util/status.cc",
-        "src/cpp/util/string_ref.cc",
-        "src/cpp/util/time_cc.cc",
+        "src/core/lib/surface/init.cc",
+        "src/core/plugin_registry/grpc_plugin_registry.cc",
     ],
+    whole_static_libs: grpc_common_libs + [
+        "libgrpc_lb_policy_grpclb_secure",
+        "libgrpc_secure",
+        "libgrpc_transport_chttp2_client_secure",
+        "libgrpc_transport_chttp2_server_secure",
+    ],
+    export_include_dirs: [
+        "include",
+        ".",
+    ],
+    local_include_dirs: [
+        "third_party/cares",
+        "third_party/cares/config_android",
+    ],
+}
+
+GRPCXX_SRCS = [
+    "src/cpp/client/channel_cc.cc",
+    "src/cpp/client/client_context.cc",
+    "src/cpp/client/create_channel.cc",
+    "src/cpp/client/create_channel_internal.cc",
+    "src/cpp/client/create_channel_posix.cc",
+    "src/cpp/client/credentials_cc.cc",
+    "src/cpp/client/generic_stub.cc",
+    "src/cpp/common/alarm.cc",
+    "src/cpp/common/channel_arguments.cc",
+    "src/cpp/common/channel_filter.cc",
+    "src/cpp/common/completion_queue_cc.cc",
+    "src/cpp/common/core_codegen.cc",
+    "src/cpp/common/resource_quota_cc.cc",
+    "src/cpp/common/rpc_method.cc",
+    "src/cpp/common/version_cc.cc",
+    "src/cpp/server/async_generic_service.cc",
+    "src/cpp/server/channel_argument_option.cc",
+    "src/cpp/server/create_default_thread_pool.cc",
+    "src/cpp/server/dynamic_thread_pool.cc",
+    "src/cpp/server/health/default_health_check_service.cc",
+    "src/cpp/server/health/health.pb.c",
+    "src/cpp/server/health/health_check_service.cc",
+    "src/cpp/server/health/health_check_service_server_builder_option.cc",
+    "src/cpp/server/server_builder.cc",
+    "src/cpp/server/server_cc.cc",
+    "src/cpp/server/server_context.cc",
+    "src/cpp/server/server_credentials.cc",
+    "src/cpp/server/server_posix.cc",
+    "src/cpp/thread_manager/thread_manager.cc",
+    "src/cpp/util/byte_buffer_cc.cc",
+    "src/cpp/util/status.cc",
+    "src/cpp/util/string_ref.cc",
+    "src/cpp/util/time_cc.cc",
+]
+
+cc_library_static {
+    name: "libgrpc++_base",
+    defaults: ["grpc_defaults"],
+    srcs: GRPCXX_SRCS,
     local_include_dirs: [
         "include",
     ],
     static_libs: [
-        "census",
-        "libgrpc_base",
+        "libgrpc",
+    ],
+    whole_static_libs: [
         "libgrpc++_codegen_base_src",
-        "libgrpc_client_channel",
-        "libgrpc_client_authority_filter",
-        "libgrpc_deadline_filter",
-        "libgrpc_resolver_dns_native",
-        "libgrpc_http_filters",
-        "libgrpc_lb_policy_grpclb",
-        "libgrpc_lb_policy_pick_first",
-        "libgrpc_lb_policy_round_robin",
-        "libgrpc_max_age_filter",
-        "libgrpc_message_size_filter",
-        "libgrpc_resolver_dns_ares",
-        "libgrpc_resolver_dns_native",
-        "libgrpc_resolver_fake",
-        "libgrpc_resolver_sockaddr",
-        "libgrpc_server_backward_compatibility",
-        "libgrpc_transport_chttp2",
-        "libgrpc_transport_chttp2_client_connector",
-        "libgrpc_transport_chttp2_client_insecure",
-        "libgrpc_transport_chttp2_server_insecure",
-        "libgrpc_transport_inproc",
+    ],
+    cflags: [
+        "-Wno-unused-parameter",
+    ],
+}
+
+cc_library_static {
+    name: "libgrpc++_base_unsecure",
+    defaults: ["grpc_defaults"],
+    srcs: GRPCXX_SRCS,
+    local_include_dirs: [
+        "include",
+    ],
+    static_libs: [
         "libgrpc_unsecure",
-        "libgrpc_workaround_cronet_compression_filter",
-        "libprotobuf-c-nano",
+    ],
+    whole_static_libs: [
+        "libgrpc++_codegen_base_src",
     ],
     cflags: [
         "-Wno-unused-parameter",
@@ -834,10 +1086,7 @@
         "src/core/lib/surface/lame_client.cc",
     ],
     whole_static_libs: [
-        "gpr_base",
         "libgrpc_base_c",
-        "libgrpc_trace",
-        "libz",
     ],
     shared_libs: [
         "liblog",
@@ -854,42 +1103,45 @@
         "src/cpp/server/insecure_server_credentials.cc",
     ],
     static_libs: [
-        "census",
-        "libgrpc_base",
-        "libgrpc++_codegen_base_src",
-        "libgrpc_base_c",
-        "libgrpc_client_channel",
-        "libgrpc_client_authority_filter",
-        "libgrpc_deadline_filter",
-        "libgrpc_resolver_dns_native",
-        "libgrpc_http_filters",
-        "libgrpc_lb_policy_grpclb",
-        "libgrpc_lb_policy_pick_first",
-        "libgrpc_lb_policy_round_robin",
-        "libgrpc_max_age_filter",
-        "libgrpc_message_size_filter",
-        "libgrpc_resolver_dns_ares",
-        "libgrpc_resolver_dns_native",
-        "libgrpc_resolver_fake",
-        "libgrpc_resolver_sockaddr",
-        "libgrpc_server_backward_compatibility",
-        "libgrpc_transport_chttp2",
-        "libgrpc_transport_chttp2_client_connector",
-        "libgrpc_transport_chttp2_client_insecure",
-        "libgrpc_transport_chttp2_server_insecure",
-        "libgrpc_transport_inproc",
-        "libgrpc_trace",
         "libgrpc_unsecure",
-        "libgrpc_workaround_cronet_compression_filter",
-        "libz",
-        "libprotobuf-c-nano",
+    ],
+    whole_static_libs: [
+        "libgrpc++_base_unsecure",
     ],
     shared_libs: [
         "liblog",
     ],
+    export_include_dirs: [
+        "include",
+        ".",
+    ],
+}
+
+// Secured gRPC C++ library target
+cc_library_shared {
+    name: "libgrpc++",
+    defaults: ["grpc_defaults"],
+    srcs: [
+        "src/cpp/client/insecure_credentials.cc",
+        "src/cpp/client/secure_credentials.cc",
+        "src/cpp/common/auth_property_iterator.cc",
+        "src/cpp/common/secure_auth_context.cc",
+        "src/cpp/common/secure_channel_arguments.cc",
+        "src/cpp/common/secure_create_auth_context.cc",
+        "src/cpp/server/insecure_server_credentials.cc",
+        "src/cpp/server/secure_server_credentials.cc",
+    ],
+    static_libs: [
+        "libgrpc",
+    ],
     whole_static_libs: [
         "libgrpc++_base",
     ],
+    shared_libs: [
+        "liblog",
+        "libcrypto",
+        "libssl",
+    ],
     export_include_dirs: [
         "include",
         ".",
@@ -899,14 +1151,14 @@
 // gRPC python library target
 python_library_host {
     name: "py-grpc",
-    srcs: [ "src/python/**/*.py" ],
+    srcs: ["src/python/**/*.py"],
     version: {
         py2: {
-	    enabled: true,
-	},
-	py3: {
-	    enabled: true,
-	},
+            enabled: true,
+        },
+        py3: {
+            enabled: true,
+        },
     },
-    pkg_path: "grpc"
-}
\ No newline at end of file
+    pkg_path: "grpc",
+}
diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h
index 1dd7c05..059fb3f 100644
--- a/include/grpc/impl/codegen/port_platform.h
+++ b/include/grpc/impl/codegen/port_platform.h
@@ -141,6 +141,7 @@
 #define GPR_POSIX_TIME 1
 #define GPR_GETPID_IN_UNISTD_H 1
 #define GPR_SUPPORT_CHANNELS_FROM_FD 1
+#include <linux/version.h>
 #elif defined(__linux__)
 #define GPR_PLATFORM_STRING "linux"
 #ifndef _BSD_SOURCE
diff --git a/src/core/ext/filters/client_channel/parse_address.cc b/src/core/ext/filters/client_channel/parse_address.cc
index 707beb8..c737f53 100644
--- a/src/core/ext/filters/client_channel/parse_address.cc
+++ b/src/core/ext/filters/client_channel/parse_address.cc
@@ -26,6 +26,10 @@
 #include <string.h>
 #ifdef GRPC_HAVE_UNIX_SOCKET
 #include <sys/un.h>
+#ifdef GRPC_HAVE_LINUX_VSOCK
+#include <sys/socket.h>
+#include <linux/vm_sockets.h>
+#endif /* GRPC_HAVE_LINUX_VSOCK */
 #endif
 
 #include <grpc/support/alloc.h>
@@ -63,6 +67,32 @@
 
 #endif /* GRPC_HAVE_UNIX_SOCKET */
 
+#if defined(GRPC_HAVE_UNIX_SOCKET) && defined(GRPC_HAVE_LINUX_VSOCK)
+
+bool grpc_parse_vsock(const grpc_uri* uri,
+                      grpc_resolved_address* resolved_addr) {
+  memset(resolved_addr, 0, sizeof(*resolved_addr));
+  struct sockaddr_vm *vm =
+      reinterpret_cast<struct sockaddr_vm *>(resolved_addr->addr);
+
+  if (sscanf(uri->path, "%u:%u", &vm->svm_cid, &vm->svm_port) != 2) {
+    return false;
+  }
+  vm->svm_family = AF_VSOCK;
+
+  resolved_addr->len = static_cast<socklen_t>(sizeof(*vm));
+  return true;
+}
+
+#else /* defined(GRPC_HAVE_UNIX_SOCKET) && defined(GRPC_HAVE_LINUX_VSOCK) */
+
+bool grpc_parse_vsock(const grpc_uri* uri,
+                      grpc_resolved_address* resolved_addr) {
+  abort();
+}
+
+#endif /* defined(GRPC_HAVE_UNIX_SOCKET) && defined(GRPC_HAVE_LINUX_VSOCK) */
+
 bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr,
                               bool log_errors) {
   bool success = false;
@@ -200,6 +230,8 @@
     return grpc_parse_ipv4(uri, resolved_addr);
   } else if (strcmp("ipv6", uri->scheme) == 0) {
     return grpc_parse_ipv6(uri, resolved_addr);
+  } else if (strcmp("vsock", uri->scheme) == 0) {
+    return grpc_parse_vsock(uri, resolved_addr);
   }
   gpr_log(GPR_ERROR, "Can't parse scheme '%s'", uri->scheme);
   return false;
diff --git a/src/core/ext/filters/client_channel/parse_address.h b/src/core/ext/filters/client_channel/parse_address.h
index c2af0e6..2e7356f 100644
--- a/src/core/ext/filters/client_channel/parse_address.h
+++ b/src/core/ext/filters/client_channel/parse_address.h
@@ -30,6 +30,11 @@
  * unix socket path. Returns true upon success. */
 bool grpc_parse_unix(const grpc_uri* uri, grpc_resolved_address* resolved_addr);
 
+/** Populate \a resolved_addr from \a uri, whose path is expected to contain a
+ * vsock specification. Returns true upon success. */
+bool grpc_parse_vsock(const grpc_uri* uri,
+                      grpc_resolved_address* resolved_addr);
+
 /** Populate \a resolved_addr from \a uri, whose path is expected to contain an
  * IPv4 host:port pair. Returns true upon success. */
 bool grpc_parse_ipv4(const grpc_uri* uri, grpc_resolved_address* resolved_addr);
diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h
index 3d45905..fde2627 100644
--- a/src/core/lib/iomgr/port.h
+++ b/src/core/lib/iomgr/port.h
@@ -49,6 +49,11 @@
 #define GRPC_HAVE_IP_PKTINFO 1
 #define GRPC_HAVE_MSG_NOSIGNAL 1
 #define GRPC_HAVE_UNIX_SOCKET 1
+#ifdef LINUX_VERSION_CODE
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+#define GRPC_HAVE_LINUX_VSOCK
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0) */
+#endif /* LINUX_VERSION_CODE */
 #define GRPC_LINUX_EVENTFD 1
 #define GRPC_POSIX_SOCKET 1
 #define GRPC_POSIX_SOCKETUTILS 1
@@ -65,6 +70,11 @@
 #define GRPC_LINUX_ERRQUEUE 1
 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) */
 #endif /* LINUX_VERSION_CODE */
+#ifdef LINUX_VERSION_CODE
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+#define GRPC_HAVE_LINUX_VSOCK
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0) */
+#endif /* LINUX_VERSION_CODE */
 #define GRPC_LINUX_MULTIPOLL_WITH_EPOLL 1
 #define GRPC_POSIX_FORK 1
 #define GRPC_POSIX_HOST_NAME_MAX 1
diff --git a/src/core/lib/iomgr/resolve_address_posix.cc b/src/core/lib/iomgr/resolve_address_posix.cc
index c285d7e..cad143d 100644
--- a/src/core/lib/iomgr/resolve_address_posix.cc
+++ b/src/core/lib/iomgr/resolve_address_posix.cc
@@ -59,6 +59,11 @@
     return grpc_resolve_unix_domain_address(name + 5, addresses);
   }
 
+  if (name[0] == 'v' && name[1] == 's' && name[2] == 'o' && name[3] == 'c' &&
+      name[4] == 'k' && name[5] == ':' && name[6] != 0) {
+    return grpc_resolve_vsock_address(name + 6, addresses);
+  }
+
   /* parse name, splitting it into host and port parts */
   gpr_split_host_port(name, &host, &port);
   if (host == nullptr) {
diff --git a/src/core/lib/iomgr/sockaddr_posix.h b/src/core/lib/iomgr/sockaddr_posix.h
index 3cedd90..e32fc9a 100644
--- a/src/core/lib/iomgr/sockaddr_posix.h
+++ b/src/core/lib/iomgr/sockaddr_posix.h
@@ -48,8 +48,13 @@
 #define GRPC_AF_INET AF_INET
 #define GRPC_AF_INET6 AF_INET6
 
+#ifdef GRPC_HAVE_LINUX_VSOCK
+#include <linux/vm_sockets.h>  // Needs to come after sys/socket.h
+#define GRPC_AF_VSOCK AF_VSOCK
+#endif /* GRPC_HAVE_LINUX_VSOCK */
+
 #define GRPC_AI_PASSIVE AI_PASSIVE
 
-#endif
+#endif /* GRPC_POSIX_SOCKET_SOCKADDR */
 
 #endif /* GRPC_CORE_LIB_IOMGR_SOCKADDR_POSIX_H */
diff --git a/src/core/lib/iomgr/sockaddr_utils.cc b/src/core/lib/iomgr/sockaddr_utils.cc
index 1b66dce..833b566 100644
--- a/src/core/lib/iomgr/sockaddr_utils.cc
+++ b/src/core/lib/iomgr/sockaddr_utils.cc
@@ -224,6 +224,8 @@
   const char* scheme = grpc_sockaddr_get_uri_scheme(resolved_addr);
   if (scheme == nullptr || strcmp("unix", scheme) == 0) {
     return grpc_sockaddr_to_uri_unix_if_possible(resolved_addr);
+  } else if (strcmp("vsock", scheme) == 0) {
+    return grpc_sockaddr_to_uri_vsock_if_possible(resolved_addr);
   }
   char* path = nullptr;
   char* uri_str = nullptr;
@@ -247,6 +249,10 @@
       return "ipv6";
     case GRPC_AF_UNIX:
       return "unix";
+#ifdef GRPC_AF_VSOCK
+    case GRPC_AF_VSOCK:
+      return "vsock";
+#endif /* GRPC_AF_VSOCK */
   }
   return nullptr;
 }
@@ -265,6 +271,15 @@
       return grpc_ntohs(((grpc_sockaddr_in*)addr)->sin_port);
     case GRPC_AF_INET6:
       return grpc_ntohs(((grpc_sockaddr_in6*)addr)->sin6_port);
+#ifdef GRPC_AF_VSOCK
+    case GRPC_AF_VSOCK:
+#ifdef GRPC_HAVE_LINUX_VSOCK
+      return static_cast<int>(reinterpret_cast<const struct sockaddr_vm *>(addr)->svm_port);
+#else /* GRPC_HAVE_LINUX_VSOCK */
+      gpr_log(GPR_ERROR, "Unknown vsock implementation");
+      return 0;
+#endif /* GRPC_HAVE_LINUX_VSOCK */
+#endif /* GRPC_AF_VSOCK */
     default:
       if (grpc_is_unix_socket(resolved_addr)) {
         return 1;
@@ -277,8 +292,8 @@
 
 int grpc_sockaddr_set_port(const grpc_resolved_address* resolved_addr,
                            int port) {
-  const grpc_sockaddr* addr =
-      reinterpret_cast<const grpc_sockaddr*>(resolved_addr->addr);
+  grpc_sockaddr* addr =
+      const_cast<grpc_sockaddr*>(reinterpret_cast<const grpc_sockaddr*>(resolved_addr->addr));
   switch (addr->sa_family) {
     case GRPC_AF_INET:
       GPR_ASSERT(port >= 0 && port < 65536);
@@ -290,6 +305,16 @@
       ((grpc_sockaddr_in6*)addr)->sin6_port =
           grpc_htons(static_cast<uint16_t>(port));
       return 1;
+#ifdef GRPC_AF_VSOCK
+    case GRPC_AF_VSOCK:
+#ifdef GRPC_HAVE_LINUX_VSOCK
+      reinterpret_cast<struct sockaddr_vm *>(addr)->svm_port = static_cast<unsigned int>(port);
+      return 1;
+#else /* GRPC_HAVE_LINUX_VSOCK */
+      gpr_log(GPR_ERROR, "Unknown vsock implementation");
+      return 0;
+#endif /* GRPC_HAVE_LINUX_VSOCK */
+#endif /* GRPC_AF_VSOCK */
     default:
       gpr_log(GPR_ERROR, "Unknown socket family %d in grpc_sockaddr_set_port",
               addr->sa_family);
diff --git a/src/core/lib/iomgr/tcp_client_posix.cc b/src/core/lib/iomgr/tcp_client_posix.cc
index 8553ed0..207f748 100644
--- a/src/core/lib/iomgr/tcp_client_posix.cc
+++ b/src/core/lib/iomgr/tcp_client_posix.cc
@@ -73,7 +73,7 @@
   if (err != GRPC_ERROR_NONE) goto error;
   err = grpc_set_socket_cloexec(fd, 1);
   if (err != GRPC_ERROR_NONE) goto error;
-  if (!grpc_is_unix_socket(addr)) {
+  if (!grpc_is_unix_socket(addr) && !grpc_is_vsock(addr)) {
     err = grpc_set_socket_low_latency(fd, 1);
     if (err != GRPC_ERROR_NONE) goto error;
     err = grpc_set_socket_tcp_user_timeout(fd, channel_args,
diff --git a/src/core/lib/iomgr/tcp_server_posix.cc b/src/core/lib/iomgr/tcp_server_posix.cc
index 824db07..34a54b1 100644
--- a/src/core/lib/iomgr/tcp_server_posix.cc
+++ b/src/core/lib/iomgr/tcp_server_posix.cc
@@ -487,7 +487,7 @@
   sp = s->head;
   while (sp != nullptr) {
     if (s->so_reuseport && !grpc_is_unix_socket(&sp->addr) &&
-        pollset_count > 1) {
+        !grpc_is_vsock(&sp->addr) && pollset_count > 1) {
       GPR_ASSERT(GRPC_LOG_IF_ERROR(
           "clone_port", clone_port(sp, (unsigned)(pollset_count - 1))));
       for (i = 0; i < pollset_count; i++) {
diff --git a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
index 8d8d3f4..4398bae 100644
--- a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
+++ b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
@@ -152,7 +152,8 @@
 
   GPR_ASSERT(fd >= 0);
 
-  if (so_reuseport && !grpc_is_unix_socket(addr)) {
+  if (so_reuseport && !grpc_is_unix_socket(addr) &&
+      !grpc_is_vsock(addr)) {
     err = grpc_set_socket_reuse_port(fd, 1);
     if (err != GRPC_ERROR_NONE) goto error;
   }
@@ -161,7 +162,7 @@
   if (err != GRPC_ERROR_NONE) goto error;
   err = grpc_set_socket_cloexec(fd, 1);
   if (err != GRPC_ERROR_NONE) goto error;
-  if (!grpc_is_unix_socket(addr)) {
+  if (!grpc_is_unix_socket(addr) && !grpc_is_vsock(addr)) {
     err = grpc_set_socket_low_latency(fd, 1);
     if (err != GRPC_ERROR_NONE) goto error;
     err = grpc_set_socket_reuse_addr(fd, 1);
diff --git a/src/core/lib/iomgr/udp_server.cc b/src/core/lib/iomgr/udp_server.cc
index 3dd7cab..49a5b6c 100644
--- a/src/core/lib/iomgr/udp_server.cc
+++ b/src/core/lib/iomgr/udp_server.cc
@@ -404,7 +404,7 @@
     }
   }
 
-  if (so_reuseport && !grpc_is_unix_socket(addr) &&
+  if (so_reuseport && !grpc_is_unix_socket(addr) && !grpc_is_vsock(addr) &&
       grpc_set_socket_reuse_port(fd, 1) != GRPC_ERROR_NONE) {
     gpr_log(GPR_ERROR, "Failed to set SO_REUSEPORT for fd %d", fd);
     goto error;
diff --git a/src/core/lib/iomgr/unix_sockets_posix.cc b/src/core/lib/iomgr/unix_sockets_posix.cc
index 22fcaf5..49ced55 100644
--- a/src/core/lib/iomgr/unix_sockets_posix.cc
+++ b/src/core/lib/iomgr/unix_sockets_posix.cc
@@ -19,6 +19,13 @@
 
 #include "src/core/lib/iomgr/port.h"
 
+#ifdef GRPC_HAVE_LINUX_VSOCK
+
+#include <sys/socket.h>
+#include <linux/vm_sockets.h>
+
+#endif /* GRPC_HAVE_LINUX_VSOCK */
+
 #ifdef GRPC_HAVE_UNIX_SOCKET
 
 #include "src/core/lib/iomgr/sockaddr.h"
@@ -66,12 +73,49 @@
   return GRPC_ERROR_NONE;
 }
 
+grpc_error* grpc_resolve_vsock_address(const char* name,
+                                       grpc_resolved_addresses** addrs) {
+#ifdef GRPC_HAVE_LINUX_VSOCK
+  struct sockaddr_vm *vm;
+  unsigned int cid;
+  unsigned int port;
+
+  if (sscanf(name, "%u:%u", &cid, &port) != 2) {
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to parse cid:port pair");
+  }
+
+  *addrs = static_cast<grpc_resolved_addresses*>(
+      gpr_malloc(sizeof(grpc_resolved_addresses)));
+  (*addrs)->naddrs = 1;
+  (*addrs)->addrs = static_cast<grpc_resolved_address*>(
+      gpr_zalloc(sizeof(grpc_resolved_address)));
+  vm = (struct sockaddr_vm *)(*addrs)->addrs->addr;
+  vm->svm_family = AF_VSOCK;
+  vm->svm_cid = cid;
+  vm->svm_port = port;
+  (*addrs)->addrs->len = sizeof(struct sockaddr_vm);
+  return GRPC_ERROR_NONE;
+#else /* GRPC_HAVE_LINUX_VSOCK */
+  return GRPC_ERROR_CREATE_FROM_STATIC_STRING("vsock not supported");
+#endif /* GRPC_HAVE_LINUX_VSOCK */
+}
+
 int grpc_is_unix_socket(const grpc_resolved_address* resolved_addr) {
   const grpc_sockaddr* addr =
       reinterpret_cast<const grpc_sockaddr*>(resolved_addr->addr);
   return addr->sa_family == AF_UNIX;
 }
 
+int grpc_is_vsock(const grpc_resolved_address* resolved_addr) {
+#ifdef GRPC_HAVE_LINUX_VSOCK
+  const grpc_sockaddr* addr =
+      reinterpret_cast<const grpc_sockaddr*>(resolved_addr->addr);
+  return addr->sa_family == AF_VSOCK;
+#else /* GRPC_HAVE_LINUX_VSOCK */
+  return 0;
+#endif /* GRPC_HAVE_LINUX_VSOCK */
+}
+
 void grpc_unlink_if_unix_domain_socket(
     const grpc_resolved_address* resolved_addr) {
   const grpc_sockaddr* addr =
@@ -101,4 +145,23 @@
   return result;
 }
 
+char* grpc_sockaddr_to_uri_vsock_if_possible(
+    const grpc_resolved_address* resolved_addr) {
+#ifdef GRPC_HAVE_LINUX_VSOCK
+  const grpc_sockaddr* addr =
+      reinterpret_cast<const grpc_sockaddr*>(resolved_addr->addr);
+
+  if (addr->sa_family != AF_VSOCK) {
+      return nullptr;
+  }
+
+  char *result;
+  struct sockaddr_vm *vm = (struct sockaddr_vm*)addr;
+  gpr_asprintf(&result, "vsock:%u:%u", vm->svm_cid, vm->svm_port);
+  return result;
+#else /* GRPC_HAVE_LINUX_VSOCK */
+  return nullptr;
+#endif /* GRPC_HAVE_LINUX_VSOCK */
+}
+
 #endif
diff --git a/src/core/lib/iomgr/unix_sockets_posix.h b/src/core/lib/iomgr/unix_sockets_posix.h
index 917d032..ed1f03a 100644
--- a/src/core/lib/iomgr/unix_sockets_posix.h
+++ b/src/core/lib/iomgr/unix_sockets_posix.h
@@ -32,12 +32,20 @@
 grpc_error* grpc_resolve_unix_domain_address(
     const char* name, grpc_resolved_addresses** addresses);
 
+grpc_error* grpc_resolve_vsock_address(
+    const char* name, grpc_resolved_addresses** addrs);
+
 int grpc_is_unix_socket(const grpc_resolved_address* resolved_addr);
 
+int grpc_is_vsock(const grpc_resolved_address* resolved_addr);
+
 void grpc_unlink_if_unix_domain_socket(
     const grpc_resolved_address* resolved_addr);
 
 char* grpc_sockaddr_to_uri_unix_if_possible(
     const grpc_resolved_address* resolved_addr);
 
+char* grpc_sockaddr_to_uri_vsock_if_possible(
+    const grpc_resolved_address* resolved_addr);
+
 #endif /* GRPC_CORE_LIB_IOMGR_UNIX_SOCKETS_POSIX_H */