Merge "Address comments left from aosp/2324894."
diff --git a/staticlibs/device/com/android/net/module/util/netlink/RtNetlinkAddressMessage.java b/staticlibs/device/com/android/net/module/util/netlink/RtNetlinkAddressMessage.java
index 3748e46..c07cec0 100644
--- a/staticlibs/device/com/android/net/module/util/netlink/RtNetlinkAddressMessage.java
+++ b/staticlibs/device/com/android/net/module/util/netlink/RtNetlinkAddressMessage.java
@@ -17,7 +17,6 @@
package com.android.net.module.util.netlink;
import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_ACK;
-import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_REPLACE;
import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_REQUEST;
import android.system.OsConstants;
@@ -32,6 +31,7 @@
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
+import java.util.Objects;
/**
* A NetlinkMessage subclass for rtnetlink address messages.
@@ -154,21 +154,26 @@
/**
* A convenience method to create an RTM_NEWADDR message.
*/
- public static byte[] newRtmNewAddressMessage(int seqNo, final InetAddress ip, short prefixlen,
- byte flags, byte scope, int ifIndex, long preferred, long valid) {
+ public static byte[] newRtmNewAddressMessage(int seqNo, @NonNull final InetAddress ip,
+ short prefixlen, int flags, byte scope, int ifIndex, long preferred, long valid) {
+ Objects.requireNonNull(ip, "IP address to be set via netlink message cannot be null");
+
final StructNlMsgHdr nlmsghdr = new StructNlMsgHdr();
nlmsghdr.nlmsg_type = NetlinkConstants.RTM_NEWADDR;
- nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_REPLACE;
+ nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
nlmsghdr.nlmsg_seq = seqNo;
final RtNetlinkAddressMessage msg = new RtNetlinkAddressMessage(nlmsghdr);
final byte family =
(byte) ((ip instanceof Inet6Address) ? OsConstants.AF_INET6 : OsConstants.AF_INET);
- msg.mIfaddrmsg = new StructIfaddrMsg(family, prefixlen, flags, scope, ifIndex);
+ // IFA_FLAGS attribute is always present within this method, just set flags from
+ // ifaddrmsg to 0. kernel will prefer the flags from IFA_FLAGS attribute.
+ msg.mIfaddrmsg =
+ new StructIfaddrMsg(family, prefixlen, (short) 0 /* flags */, scope, ifIndex);
msg.mIpAddress = ip;
msg.mIfacacheInfo = new StructIfacacheInfo(preferred, valid, 0 /* cstamp */,
0 /* tstamp */);
- msg.mFlags = (int) (flags & 0xFF);
+ msg.mFlags = flags;
final byte[] bytes = new byte[msg.getRequiredSpace()];
nlmsghdr.nlmsg_len = bytes.length;
@@ -180,15 +185,14 @@
private int getRequiredSpace() {
int spaceRequired = StructNlMsgHdr.STRUCT_SIZE + StructIfaddrMsg.STRUCT_SIZE;
- if (mIpAddress != null) {
- spaceRequired += NetlinkConstants.alignedLengthOf(
- StructNlAttr.NLA_HEADERLEN + mIpAddress.getAddress().length);
- }
- if (mIfacacheInfo != null) {
- spaceRequired += NetlinkConstants.alignedLengthOf(
- StructNlAttr.NLA_HEADERLEN + StructIfacacheInfo.STRUCT_SIZE);
- }
- spaceRequired += StructNlAttr.NLA_HEADERLEN + 4; // IFA_FLAGS "u32" attr
+ // IFA_ADDRESS attr
+ spaceRequired += NetlinkConstants.alignedLengthOf(
+ StructNlAttr.NLA_HEADERLEN + mIpAddress.getAddress().length);
+ // IFA_CACHEINFO attr
+ spaceRequired += NetlinkConstants.alignedLengthOf(
+ StructNlAttr.NLA_HEADERLEN + StructIfacacheInfo.STRUCT_SIZE);
+ // IFA_FLAGS "u32" attr
+ spaceRequired += StructNlAttr.NLA_HEADERLEN + 4;
return spaceRequired;
}
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkAddressMessageTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkAddressMessageTest.java
index b21e060..f845eb4 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkAddressMessageTest.java
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkAddressMessageTest.java
@@ -19,6 +19,9 @@
import static android.system.OsConstants.IFA_F_PERMANENT;
import static android.system.OsConstants.NETLINK_ROUTE;
import static android.system.OsConstants.RT_SCOPE_LINK;
+import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
+
+import static com.android.testutils.MiscAsserts.assertThrows;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@@ -48,6 +51,8 @@
public class RtNetlinkAddressMessageTest {
private static final Inet6Address TEST_LINK_LOCAL =
(Inet6Address) InetAddresses.parseNumericAddress("FE80::2C41:5CFF:FE09:6665");
+ private static final Inet6Address TEST_GLOBAL_ADDRESS =
+ (Inet6Address) InetAddresses.parseNumericAddress("2001:DB8:1::100");
// An example of the full RTM_NEWADDR message.
private static final String RTM_NEWADDR_HEX =
@@ -139,13 +144,13 @@
// struct nlmsghdr
"48000000" + // length = 72
"1400" + // type = 20 (RTM_NEWADDR)
- "0501" + // flags = NLM_F_ACK | NLM_F_REQUEST | NLM_F_REPLACE
+ "0500" + // flags = NLM_F_ACK | NLM_F_REQUEST
"01000000" + // seqno = 1
"00000000" + // pid = 0 (send to kernel)
// struct IfaddrMsg
"0A" + // family = inet6
"40" + // prefix len = 64
- "80" + // flags = IFA_F_PERMANENT
+ "00" + // flags = 0
"FD" + // scope = RT_SCOPE_LINK
"17000000" + // ifindex = 23
// struct nlattr: IFA_ADDRESS
@@ -167,13 +172,65 @@
HexEncoding.decode(expectedNewAddressHex.toCharArray(), false);
final byte[] bytes = RtNetlinkAddressMessage.newRtmNewAddressMessage(1 /* seqno */,
- TEST_LINK_LOCAL, (short) 64 /* prefix len */, (byte) IFA_F_PERMANENT /* flags */,
+ TEST_LINK_LOCAL, (short) 64 /* prefix len */, IFA_F_PERMANENT /* flags */,
(byte) RT_SCOPE_LINK /* scope */, 23 /* ifindex */,
(long) 0xFFFFFFFF /* preferred */, (long) 0xFFFFFFFF /* valid */);
assertArrayEquals(expectedNewAddress, bytes);
}
@Test
+ public void testCreateRtmNewAddressMessage_nullIpAddress() {
+ assertThrows(NullPointerException.class,
+ () -> RtNetlinkAddressMessage.newRtmNewAddressMessage(1 /* seqno */,
+ null /* IP address */, (short) 0 /* prefix len */,
+ IFA_F_PERMANENT /* flags */, (byte) RT_SCOPE_LINK /* scope */,
+ 23 /* ifindex */, (long) 0xFFFFFFFF /* preferred */,
+ (long) 0xFFFFFFFF /* valid */));
+ }
+
+ @Test
+ public void testCreateRtmNewAddressMessage_u32Flags() {
+ // Hexadecimal representation of our created packet.
+ final String expectedNewAddressHex =
+ // struct nlmsghdr
+ "48000000" + // length = 72
+ "1400" + // type = 20 (RTM_NEWADDR)
+ "0500" + // flags = NLM_F_ACK | NLM_F_REQUEST
+ "01000000" + // seqno = 1
+ "00000000" + // pid = 0 (send to kernel)
+ // struct IfaddrMsg
+ "0A" + // family = inet6
+ "80" + // prefix len = 128
+ "00" + // flags = 0
+ "00" + // scope = RT_SCOPE_UNIVERSE
+ "17000000" + // ifindex = 23
+ // struct nlattr: IFA_ADDRESS
+ "1400" + // len
+ "0100" + // type
+ "20010DB8000100000000000000000100" + // IP address = 2001:db8:1::100
+ // struct nlattr: IFA_CACHEINFO
+ "1400" + // len
+ "0600" + // type
+ "FFFFFFFF" + // preferred = infinite
+ "FFFFFFFF" + // valid = infinite
+ "00000000" + // cstamp
+ "00000000" + // tstamp
+ // struct nlattr: IFA_FLAGS
+ "0800" + // len
+ "0800" + // type
+ "00030000"; // flags = IFA_F_MANAGETEMPADDR | IFA_F_NOPREFIXROUTE
+ final byte[] expectedNewAddress =
+ HexEncoding.decode(expectedNewAddressHex.toCharArray(), false);
+
+ final byte[] bytes = RtNetlinkAddressMessage.newRtmNewAddressMessage(1 /* seqno */,
+ TEST_GLOBAL_ADDRESS, (short) 128 /* prefix len */,
+ (int) 0x300 /* flags: IFA_F_MANAGETEMPADDR | IFA_F_NOPREFIXROUTE */,
+ (byte) RT_SCOPE_UNIVERSE /* scope */, 23 /* ifindex */,
+ (long) 0xFFFFFFFF /* preferred */, (long) 0xFFFFFFFF /* valid */);
+ assertArrayEquals(expectedNewAddress, bytes);
+ }
+
+ @Test
public void testToString() {
final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWADDR_HEX);
byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing.