Merge "Add UDP_GRO and UDP_SEGMENT Socket Options"
diff --git a/api/current.txt b/api/current.txt
index ac9f19a..e849e72 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -477,6 +477,7 @@
field public static final int SOCK_SEQPACKET;
field public static final int SOCK_STREAM;
field public static final int SOL_SOCKET;
+ field public static final int SOL_UDP;
field public static final int SO_BINDTODEVICE;
field public static final int SO_BROADCAST;
field public static final int SO_DEBUG;
@@ -532,6 +533,8 @@
field public static final int S_IXUSR;
field public static final int TCP_NODELAY;
field public static final int TCP_USER_TIMEOUT;
+ field public static final int UDP_GRO;
+ field public static final int UDP_SEGMENT;
field public static final int WCONTINUED;
field public static final int WEXITED;
field public static final int WNOHANG;
diff --git a/luni/src/main/java/android/system/OsConstants.java b/luni/src/main/java/android/system/OsConstants.java
index 1b0dc16..7f2182c 100644
--- a/luni/src/main/java/android/system/OsConstants.java
+++ b/luni/src/main/java/android/system/OsConstants.java
@@ -560,6 +560,7 @@
public static final int SOCK_SEQPACKET = placeholder();
public static final int SOCK_STREAM = placeholder();
public static final int SOL_SOCKET = placeholder();
+ public static final int SOL_UDP = placeholder();
public static final int SO_BINDTODEVICE = placeholder();
public static final int SO_BROADCAST = placeholder();
public static final int SO_DEBUG = placeholder();
@@ -632,6 +633,8 @@
public static final int S_IXUSR = placeholder();
public static final int TCP_NODELAY = placeholder();
public static final int TCP_USER_TIMEOUT = placeholder();
+ public static final int UDP_GRO = placeholder();
+ public static final int UDP_SEGMENT = placeholder();
/** @hide */
@UnsupportedAppUsage
@libcore.api.CorePlatformApi
diff --git a/luni/src/main/native/android_system_OsConstants.cpp b/luni/src/main/native/android_system_OsConstants.cpp
index 6cf2c8b..450995b 100644
--- a/luni/src/main/native/android_system_OsConstants.cpp
+++ b/luni/src/main/native/android_system_OsConstants.cpp
@@ -522,6 +522,9 @@
initConstant(env, c, "SOCK_SEQPACKET", SOCK_SEQPACKET);
initConstant(env, c, "SOCK_STREAM", SOCK_STREAM);
initConstant(env, c, "SOL_SOCKET", SOL_SOCKET);
+#if defined(SOL_UDP)
+ initConstant(env, c, "SOL_UDP", SOL_UDP);
+#endif
#if defined(SO_BINDTODEVICE)
initConstant(env, c, "SO_BINDTODEVICE", SO_BINDTODEVICE);
#endif
@@ -598,6 +601,12 @@
initConstant(env, c, "UDP_ENCAP", UDP_ENCAP);
initConstant(env, c, "UDP_ENCAP_ESPINUDP_NON_IKE", UDP_ENCAP_ESPINUDP_NON_IKE);
initConstant(env, c, "UDP_ENCAP_ESPINUDP", UDP_ENCAP_ESPINUDP);
+#if defined(UDP_GRO)
+ initConstant(env, c, "UDP_GRO", UDP_GRO);
+#endif
+#if defined(UDP_SEGMENT)
+ initConstant(env, c, "UDP_SEGMENT", UDP_SEGMENT);
+#endif
// UNIX_PATH_MAX is mentioned in some versions of unix(7), but not actually declared.
initConstant(env, c, "UNIX_PATH_MAX", sizeof(sockaddr_un::sun_path));
initConstant(env, c, "WCONTINUED", WCONTINUED);
diff --git a/luni/src/test/java/libcore/android/system/OsTest.java b/luni/src/test/java/libcore/android/system/OsTest.java
index 355d340..9cc25e9 100644
--- a/luni/src/test/java/libcore/android/system/OsTest.java
+++ b/luni/src/test/java/libcore/android/system/OsTest.java
@@ -52,6 +52,8 @@
import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import junit.framework.TestCase;
@@ -1044,6 +1046,50 @@
}
}
+ private double getKernelVersion() {
+ // Example:
+ // 4.9.29-g958411d --> 4.9
+ String release = Os.uname().release;
+ Matcher m = Pattern.compile("^(\\d+)\\.(\\d+)").matcher(release);
+ assertTrue("No pattern in release string: " + release, m.find());
+ double version = Double.parseDouble(m.group(1) + "." + m.group(2));
+ return version;
+ }
+
+ public void test_socket_udpGro_setAndGet() throws Exception {
+ // UDP GRO not required to be enabled on kernels prior to 5.4
+ double kernelVersion = getKernelVersion();
+ if (kernelVersion < 5.4) return;
+
+ final FileDescriptor fd = Os.socket(AF_INET6, SOCK_DGRAM, 0);
+ try {
+ assertEquals(0, Os.getsockoptInt(fd, IPPROTO_UDP, UDP_GRO));
+
+ final int setValue = 1;
+ Os.setsockoptInt(fd, IPPROTO_UDP, UDP_GRO, setValue);
+ assertEquals(setValue, Os.getsockoptInt(fd, IPPROTO_UDP, UDP_GRO));
+ } finally {
+ Os.close(fd);
+ }
+ }
+
+ public void test_socket_udpGso_setAndGet() throws Exception {
+ // UDP GSO not required to be enabled on kernels prior to 4.19.
+ double kernelVersion = getKernelVersion();
+ if (kernelVersion < 4.19) return;
+
+ final FileDescriptor fd = Os.socket(AF_INET, SOCK_DGRAM, 0);
+ try {
+ assertEquals(0, Os.getsockoptInt(fd, IPPROTO_UDP, UDP_SEGMENT));
+
+ final int setValue = 1452;
+ Os.setsockoptInt(fd, IPPROTO_UDP, UDP_SEGMENT, setValue);
+ assertEquals(setValue, Os.getsockoptInt(fd, IPPROTO_UDP, UDP_SEGMENT));
+ } finally {
+ Os.close(fd);
+ }
+ }
+
/**
* Tests that TCP_USER_TIMEOUT can be set on a TCP socket, but doesn't test
* that it behaves as expected.