Parse IFLA_INET6_FLAGS attr from the RTM_NEWLINK message.
Flag: EXEMPT mainline change Bug: 293393743 Test: atest NetworkStaticLibTests Change-Id: I5dc34461a13bd0751d3d7debf1e7412f05958734
This commit is contained in:
parent
32d4c35ae8
commit
d4de245c84
2 changed files with 98 additions and 6 deletions
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package com.android.net.module.util.netlink;
|
||||
|
||||
import static android.system.OsConstants.AF_INET6;
|
||||
import static android.system.OsConstants.AF_UNSPEC;
|
||||
|
||||
import static com.android.net.module.util.NetworkStackConstants.ETHER_ADDR_LEN;
|
||||
|
|
@ -53,6 +54,7 @@ public class RtNetlinkLinkMessage extends NetlinkMessage {
|
|||
public static final short IFLA_MTU = 4;
|
||||
public static final short IFLA_INET6_ADDR_GEN_MODE = 8;
|
||||
public static final short IFLA_AF_SPEC = 26;
|
||||
public static final short IFLA_INET6_FLAGS = 1;
|
||||
|
||||
public static final short IN6_ADDR_GEN_MODE_NONE = 1;
|
||||
|
||||
|
|
@ -60,6 +62,8 @@ public class RtNetlinkLinkMessage extends NetlinkMessage {
|
|||
private static final int IFNAMSIZ = 16;
|
||||
// The default value of MTU, which means the MTU is unspecified.
|
||||
private static final int DEFAULT_MTU = 0;
|
||||
// The default value of IPv6 link attribute flags.
|
||||
private static final int DEFAULT_IFLA_INET6_FLAGS = 0;
|
||||
|
||||
@NonNull
|
||||
private final StructIfinfoMsg mIfinfomsg;
|
||||
|
|
@ -69,6 +73,24 @@ public class RtNetlinkLinkMessage extends NetlinkMessage {
|
|||
@Nullable
|
||||
private final String mInterfaceName;
|
||||
|
||||
// IPv6 operational flags for the interface, from the IFLA_INET6_FLAGS netlink attribute.
|
||||
// also see inet6_dev.if_flags in if_inet6.h
|
||||
private final int mInet6Flags;
|
||||
|
||||
/**
|
||||
* Creates an {@link RtNetlinkLinkMessage} instance.
|
||||
*
|
||||
* @return A new {@link RtNetlinkLinkMessage} instance, or {@code null} if the input arguments
|
||||
* are invalid.
|
||||
*/
|
||||
@Nullable
|
||||
public static RtNetlinkLinkMessage build(@NonNull StructNlMsgHdr nlmsghdr,
|
||||
@NonNull StructIfinfoMsg ifinfomsg, int mtu, @Nullable MacAddress hardwareAddress,
|
||||
@Nullable String interfaceName) {
|
||||
return RtNetlinkLinkMessage.build(nlmsghdr, ifinfomsg, mtu, hardwareAddress, interfaceName,
|
||||
DEFAULT_IFLA_INET6_FLAGS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@link RtNetlinkLinkMessage} instance.
|
||||
*
|
||||
|
|
@ -80,13 +102,14 @@ public class RtNetlinkLinkMessage extends NetlinkMessage {
|
|||
* @param mtu The Maximum Transmission Unit (MTU) value for the link.
|
||||
* @param hardwareAddress The hardware address (MAC address) of the link. May be {@code null}.
|
||||
* @param interfaceName The name of the interface. May be {@code null}.
|
||||
* @param inet6Flags IPv6 operational flags for the interface.
|
||||
* @return A new {@link RtNetlinkLinkMessage} instance, or {@code null} if the input arguments
|
||||
* are invalid.
|
||||
*/
|
||||
@Nullable
|
||||
public static RtNetlinkLinkMessage build(@NonNull StructNlMsgHdr nlmsghdr,
|
||||
@NonNull StructIfinfoMsg ifinfomsg, int mtu, @Nullable MacAddress hardwareAddress,
|
||||
@Nullable String interfaceName) {
|
||||
@Nullable String interfaceName, int inet6Flags) {
|
||||
if (mtu < 0) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -96,17 +119,19 @@ public class RtNetlinkLinkMessage extends NetlinkMessage {
|
|||
}
|
||||
|
||||
nlmsghdr.nlmsg_len = calculateMessageLength(mtu, hardwareAddress, interfaceName);
|
||||
return new RtNetlinkLinkMessage(nlmsghdr, ifinfomsg, mtu, hardwareAddress, interfaceName);
|
||||
return new RtNetlinkLinkMessage(nlmsghdr, ifinfomsg, mtu, hardwareAddress, interfaceName,
|
||||
inet6Flags);
|
||||
}
|
||||
|
||||
private RtNetlinkLinkMessage(@NonNull StructNlMsgHdr nlmsghdr,
|
||||
@NonNull StructIfinfoMsg ifinfomsg, int mtu, @Nullable MacAddress hardwareAddress,
|
||||
@Nullable String interfaceName) {
|
||||
@Nullable String interfaceName, int inet6Flags) {
|
||||
super(nlmsghdr);
|
||||
mIfinfomsg = ifinfomsg;
|
||||
mMtu = mtu;
|
||||
mHardwareAddress = hardwareAddress;
|
||||
mInterfaceName = interfaceName;
|
||||
mInet6Flags = inet6Flags;
|
||||
}
|
||||
|
||||
public int getMtu() {
|
||||
|
|
@ -128,6 +153,10 @@ public class RtNetlinkLinkMessage extends NetlinkMessage {
|
|||
return mInterfaceName;
|
||||
}
|
||||
|
||||
public int getInet6Flags() {
|
||||
return mInet6Flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse rtnetlink link message from {@link ByteBuffer}. This method must be called with a
|
||||
* ByteBuffer that contains exactly one netlink message.
|
||||
|
|
@ -171,7 +200,42 @@ public class RtNetlinkLinkMessage extends NetlinkMessage {
|
|||
return null;
|
||||
}
|
||||
|
||||
return new RtNetlinkLinkMessage(header, ifinfoMsg, mtu, hardwareAddress, interfaceName);
|
||||
/*
|
||||
* IFLA_AF_SPEC:
|
||||
* Contains nested attributes for address family specific attributes.
|
||||
* Each address family may create a attribute with the address family
|
||||
* number as type and create its own attribute structure in it.
|
||||
*
|
||||
* Example:
|
||||
* [IFLA_AF_SPEC] = {
|
||||
* [AF_INET] = {
|
||||
* [IFLA_INET_CONF] = ...,
|
||||
* },
|
||||
* [AF_INET6] = {
|
||||
* [IFLA_INET6_FLAGS] = ...,
|
||||
* [IFLA_INET6_CONF] = ...,
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
int inet6Flags = DEFAULT_IFLA_INET6_FLAGS;
|
||||
byteBuffer.position(baseOffset);
|
||||
nlAttr = StructNlAttr.findNextAttrOfType(IFLA_AF_SPEC, byteBuffer);
|
||||
if (nlAttr != null) {
|
||||
final StructNlAttr ipv6ConfigAttrs = StructNlAttr.findNextAttrOfType(
|
||||
(short) AF_INET6,
|
||||
nlAttr.getValueAsByteBuffer());
|
||||
if (ipv6ConfigAttrs != null) {
|
||||
final StructNlAttr inet6FlagsAttr = StructNlAttr.findNextAttrOfType(
|
||||
IFLA_INET6_FLAGS,
|
||||
ipv6ConfigAttrs.getValueAsByteBuffer());
|
||||
if (inet6FlagsAttr != null) {
|
||||
inet6Flags = inet6FlagsAttr.getValueAsInt(DEFAULT_IFLA_INET6_FLAGS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new RtNetlinkLinkMessage(header, ifinfoMsg, mtu, hardwareAddress, interfaceName,
|
||||
inet6Flags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -368,7 +432,8 @@ public class RtNetlinkLinkMessage extends NetlinkMessage {
|
|||
+ "Ifinfomsg{" + mIfinfomsg + "}, "
|
||||
+ "Hardware Address{" + mHardwareAddress + "}, "
|
||||
+ "MTU{" + mMtu + "}, "
|
||||
+ "Ifname{" + mInterfaceName + "} "
|
||||
+ "Ifname{" + mInterfaceName + "}, "
|
||||
+ "IFLA_INET6_FLAGS{" + mInet6Flags + "} "
|
||||
+ "}";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -332,7 +332,8 @@ public class RtNetlinkLinkMessageTest {
|
|||
+ "Ifinfomsg{"
|
||||
+ "family: 0, type: 1, index: 30, flags: 4098, change: 0}, "
|
||||
+ "Hardware Address{92:c3:e3:c9:37:4e}, " + "MTU{1500}, "
|
||||
+ "Ifname{wlan0} "
|
||||
+ "Ifname{wlan0}, "
|
||||
+ "IFLA_INET6_FLAGS{0} "
|
||||
+ "}";
|
||||
assertEquals(expected, linkMsg.toString());
|
||||
}
|
||||
|
|
@ -358,4 +359,30 @@ public class RtNetlinkLinkMessageTest {
|
|||
final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE);
|
||||
assertNull(msg);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseRtNetlinkMessageWithMOrOBit() {
|
||||
final String msgBytes =
|
||||
"7C000000100000000100000000000000" // nlmsghdr (16 bytes)
|
||||
+ "000001000200000043100000FFFFFFFF" // ifinfomsg (16 bytes)
|
||||
+ "090003006574683000000000" // IFLA_IFNAME (12 bytes)
|
||||
+ "50001A00" // IFLA_AF_SPEC (84 bytes)
|
||||
+ "1C000200" // Nested AF_INET (28 bytes)
|
||||
+ "18000100" // Nested IFLA_INET_CONF (24 bytes)
|
||||
+ "0000000000000000000000000000000000000000" // 20 bytes of dummy payload
|
||||
+ "30000A00" // Nested AF_INET6 (48 bytes)
|
||||
+ "08000100C0000000" // Nested IFLA_INET6_FLAGS (8 bytes): M=1,O=1
|
||||
+ "24000600" // Nested IFLA_INET6_CONF (36 bytes)
|
||||
+ "00000000000000000000000000000000" // 16 bytes of dummy payload
|
||||
+ "00000000000000000000000000000000"; // 16 bytes of dummy payload
|
||||
|
||||
final ByteBuffer byteBuffer = toByteBuffer(msgBytes);
|
||||
byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing.
|
||||
final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE);
|
||||
assertNotNull(msg);
|
||||
assertTrue(msg instanceof RtNetlinkLinkMessage);
|
||||
final RtNetlinkLinkMessage linkMsg = (RtNetlinkLinkMessage) msg;
|
||||
final int flags = linkMsg.getInet6Flags();
|
||||
assertEquals(0xC0, flags);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue