diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h
index ed484118175a4eaab9ad1e1990cefb507bf9d04b..607511edc8849655722904405249ca0d1b6988ee 100644
--- a/include/grpc/impl/codegen/port_platform.h
+++ b/include/grpc/impl/codegen/port_platform.h
@@ -134,6 +134,8 @@
 #define GPR_GETPID_IN_UNISTD_H 1
 #define GPR_HAVE_MSG_NOSIGNAL 1
 #define GPR_HAVE_UNIX_SOCKET 1
+#define GPR_HAVE_IP_PKTINFO 1
+#define GPR_HAVE_IPV6_RECVPKTINFO 1
 #elif defined(__linux__)
 #define GPR_POSIX_CRASH_HANDLER 1
 #define GPR_PLATFORM_STRING "linux"
@@ -156,6 +158,8 @@
 #define GPR_POSIX_SOCKET 1
 #define GPR_POSIX_SOCKETADDR 1
 #define GPR_HAVE_UNIX_SOCKET 1
+#define GPR_HAVE_IP_PKTINFO 1
+#define GPR_HAVE_IPV6_RECVPKTINFO 1
 #ifdef __GLIBC_PREREQ
 #if __GLIBC_PREREQ(2, 9)
 #define GPR_LINUX_EVENTFD 1
@@ -217,6 +221,7 @@
 #define GPR_GETPID_IN_UNISTD_H 1
 #define GPR_HAVE_SO_NOSIGPIPE 1
 #define GPR_HAVE_UNIX_SOCKET 1
+#define GPR_HAVE_IP_PKTINFO 1
 #ifdef _LP64
 #define GPR_ARCH_64 1
 #else /* _LP64 */
@@ -246,6 +251,8 @@
 #define GPR_GETPID_IN_UNISTD_H 1
 #define GPR_HAVE_SO_NOSIGPIPE 1
 #define GPR_HAVE_UNIX_SOCKET 1
+#define GPR_HAVE_IP_PKTINFO 1
+#define GPR_HAVE_IPV6_RECVPKTINFO 1
 #ifdef _LP64
 #define GPR_ARCH_64 1
 #else /* _LP64 */
diff --git a/src/core/lib/iomgr/socket_utils_common_posix.c b/src/core/lib/iomgr/socket_utils_common_posix.c
index 9dbc2784e4c2e1e70e881308d342e6b875a175cc..b433aee7fa9203147670fc1aa4c8b7c834fe6b12 100644
--- a/src/core/lib/iomgr/socket_utils_common_posix.c
+++ b/src/core/lib/iomgr/socket_utils_common_posix.c
@@ -89,6 +89,28 @@ int grpc_set_socket_no_sigpipe_if_possible(int fd) {
 #endif
 }
 
+int grpc_set_socket_ip_pktinfo_if_possible(int fd) {
+#ifdef GPR_HAVE_IP_PKTINFO
+  int get_local_ip = 1;
+  return 0 == setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &get_local_ip,
+                         sizeof(get_local_ip));
+#else
+  (void)fd;
+  return 1;
+#endif
+}
+
+int grpc_set_socket_ipv6_recvpktinfo_if_possible(int fd) {
+#ifdef GPR_HAVE_IPV6_RECVPKTINFO
+  int get_local_ip = 1;
+  return 0 == setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &get_local_ip,
+                         sizeof(get_local_ip));
+#else
+  (void)fd;
+  return 1;
+#endif
+}
+
 /* set a socket to close on exec */
 int grpc_set_socket_cloexec(int fd, int close_on_exec) {
   int oldflags = fcntl(fd, F_GETFD, 0);
diff --git a/src/core/lib/iomgr/socket_utils_posix.h b/src/core/lib/iomgr/socket_utils_posix.h
index 063f298d72e1c5cf97c8c0cd1faae4969f098a22..f73ad6317db80276abbecf495df8ffd4930cf1b0 100644
--- a/src/core/lib/iomgr/socket_utils_posix.h
+++ b/src/core/lib/iomgr/socket_utils_posix.h
@@ -68,6 +68,16 @@ int grpc_ipv6_loopback_available(void);
    If SO_NO_SIGPIPE is not available, returns 1. */
 int grpc_set_socket_no_sigpipe_if_possible(int fd);
 
+/* Tries to set IP_PKTINFO if available on this platform.
+   Returns 1 on success, 0 on failure.
+   If IP_PKTINFO is not available, returns 1. */
+int grpc_set_socket_ip_pktinfo_if_possible(int fd);
+
+/* Tries to set IPV6_RECVPKTINFO if available on this platform.
+   Returns 1 on success, 0 on failure.
+   If IPV6_RECVPKTINFO is not available, returns 1. */
+int grpc_set_socket_ipv6_recvpktinfo_if_possible(int fd);
+
 /* An enum to keep track of IPv4/IPv6 socket modes.
 
    Currently, this information is only used when a socket is first created, but
diff --git a/src/core/lib/iomgr/udp_server.c b/src/core/lib/iomgr/udp_server.c
index 3d8bcc9c81b44c9b242cfadb3692043e4993c4df..9068109c3a00e551bd6c95303a8b77a4c198fd8b 100644
--- a/src/core/lib/iomgr/udp_server.c
+++ b/src/core/lib/iomgr/udp_server.c
@@ -208,8 +208,6 @@ static int prepare_socket(int fd, const struct sockaddr *addr,
                           size_t addr_len) {
   struct sockaddr_storage sockname_temp;
   socklen_t sockname_len;
-  int get_local_ip;
-  int rc;
 
   if (fd < 0) {
     goto error;
@@ -220,14 +218,9 @@ static int prepare_socket(int fd, const struct sockaddr *addr,
             strerror(errno));
   }
 
-  get_local_ip = 1;
-  rc = setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &get_local_ip,
-                  sizeof(get_local_ip));
-  if (rc == 0 && addr->sa_family == AF_INET6) {
-#if !defined(__APPLE__)
-    rc = setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &get_local_ip,
-                    sizeof(get_local_ip));
-#endif
+  if (grpc_set_socket_ip_pktinfo_if_possible(fd) &&
+      addr->sa_family == AF_INET6) {
+    grpc_set_socket_ipv6_recvpktinfo_if_possible(fd);
   }
 
   GPR_ASSERT(addr_len < ~(socklen_t)0);