diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php
index 255b8dc..dc976b2 100644
--- a/src/wp-includes/rest-api.php
+++ b/src/wp-includes/rest-api.php
@@ -869,23 +869,23 @@ function rest_parse_request_arg( $value, $request, $param ) {
 }
 
 /**
- * Determines if a IPv4 address is valid.
+ * Determines if an IP address is valid.
  *
- * Does not handle IPv6 addresses.
+ * Handles both IPv4 and IPv6 addresses.
  *
  * @since 4.7.0
  *
- * @param  string $ipv4 IP 32-bit address.
- * @return string|false The valid IPv4 address, otherwise false.
+ * @param  string $ip IP address.
+ * @return string|false The valid IP address, otherwise false.
  */
-function rest_is_ip_address( $ipv4 ) {
-	$pattern = '/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/';
+function rest_is_ip_address( $ip ) {
+	$ipv4_pattern = '/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/';
 
-	if ( ! preg_match( $pattern, $ipv4 ) ) {
+	if ( ! preg_match( $ipv4_pattern, $ip ) && ! Requests_IPv6::check_ipv6( $ip ) ) {
 		return false;
 	}
 
-	return $ipv4;
+	return $ip;
 }
 
 /**
@@ -1053,9 +1053,9 @@ function rest_validate_value_from_schema( $value, $args, $param = '' ) {
 					return new WP_Error( 'rest_invalid_email', __( 'The email address you provided is invalid.' ) );
 				}
 				break;
-			case 'ipv4' :
+			case 'ip' :
 				if ( ! rest_is_ip_address( $value ) ) {
-					/* translators: %s: IP address */ 
+					/* translators: %s: IP address */
 					return new WP_Error( 'rest_invalid_param', sprintf( __( '%s is not a valid IP address.' ), $value ) );
 				}
 				break;
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php
index 15e18f7..3a0ca0a 100644
--- a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php
+++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php
@@ -1115,7 +1115,7 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
 				'author_ip'     => array(
 					'description'  => __( 'IP address for the object author.' ),
 					'type'         => 'string',
-					'format'       => 'ipv4',
+					'format'       => 'ip',
 					'context'      => array( 'edit' ),
 					'default'      => '127.0.0.1',
 				),
diff --git a/tests/phpunit/tests/rest-api/rest-schema-validation.php b/tests/phpunit/tests/rest-api/rest-schema-validation.php
index 4e4a111..f504cb7 100644
--- a/tests/phpunit/tests/rest-api/rest-schema-validation.php
+++ b/tests/phpunit/tests/rest-api/rest-schema-validation.php
@@ -83,14 +83,30 @@ class WP_Test_REST_Schema_Validation extends WP_UnitTestCase {
 		$this->assertWPError( rest_validate_value_from_schema( '2016-06-30', $schema ) );
 	}
 
-	public function test_format_ipv4() {
+	public function test_format_ip() {
 		$schema = array(
 			'type'  => 'string',
-			'format' => 'ipv4',
+			'format' => 'ip',
 		);
+
+		// IPv4.
 		$this->assertTrue( rest_validate_value_from_schema( '127.0.0.1', $schema ) );
 		$this->assertWPError( rest_validate_value_from_schema( '3333.3333.3333.3333', $schema ) );
 		$this->assertWPError( rest_validate_value_from_schema( '1', $schema ) );
+
+		// IPv6.
+		$this->assertTrue( rest_validate_value_from_schema( '::1', $schema ) ); // Loopback, compressed, non-routable.
+		$this->assertTrue( rest_validate_value_from_schema( '::', $schema ) ); // Unspecified, compressed, non-routable.
+		$this->assertTrue( rest_validate_value_from_schema( '0:0:0:0:0:0:0:1', $schema ) ); // Loopback, full.
+		$this->assertTrue( rest_validate_value_from_schema( '0:0:0:0:0:0:0:0', $schema ) ); // Unspecified, full.
+		$this->assertTrue( rest_validate_value_from_schema( '2001:DB8:0:0:8:800:200C:417A', $schema ) ); // Unicast, full.
+		$this->assertTrue( rest_validate_value_from_schema( 'FF01:0:0:0:0:0:0:101', $schema ) ); // Multicast, full.
+		$this->assertTrue( rest_validate_value_from_schema( '2001:DB8::8:800:200C:417A', $schema ) ); // Unicast, compressed.
+		$this->assertTrue( rest_validate_value_from_schema( 'FF01::101', $schema ) ); // Multicast, compressed.
+		$this->assertTrue( rest_validate_value_from_schema( 'fe80::217:f2ff:fe07:ed62', $schema ) );
+		$this->assertWPError( rest_validate_value_from_schema( '', $schema ) ); // Empty string.
+		$this->assertWPError( rest_validate_value_from_schema( '2001:DB8:0:0:8:800:200C:417A:221', $schema ) ); // Unicast, full.
+		$this->assertWPError( rest_validate_value_from_schema( 'FF01::101::2', $schema ) ); // Multicast, compressed.
 	}
 
 	public function test_type_array() {
