Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 67c1cdaa authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "[NFCT.NS.3] Add netfilter conntrack event monitor" am: 9eefc742 am:...

Merge "[NFCT.NS.3] Add netfilter conntrack event monitor" am: 9eefc742 am: 2299a3e3 am: 51376199

Original change: https://android-review.googlesource.com/c/platform/packages/modules/NetworkStack/+/1462083

Change-Id: Idb1f4dba7b221b5b467d095c7182e0eb11560322
parents 70c9026f 51376199
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ filegroup {
filegroup {
    name: "tethering-module-utils-srcs",
    srcs: [
        "src/android/net/ip/ConntrackMonitor.java",
        "src/android/net/ip/InterfaceController.java",
        "src/android/net/ip/IpNeighborMonitor.java",
        "src/android/net/ip/NetlinkMonitor.java",
+79 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.net.ip;

import android.net.netlink.ConntrackMessage;
import android.net.netlink.NetlinkMessage;
import android.net.util.SharedLog;
import android.os.Handler;
import android.system.OsConstants;

import androidx.annotation.NonNull;

/**
 * ConntrackMonitor.
 *
 * Monitors the netfilter conntrack notifications and presents to callers
 * ConntrackEvents describing each event.
 *
 * @hide
 */
public class ConntrackMonitor extends NetlinkMonitor {
    private static final String TAG = ConntrackMonitor.class.getSimpleName();
    private static final boolean DBG = false;
    private static final boolean VDBG = false;

    // Reference kernel/uapi/linux/netfilter/nfnetlink_compat.h
    public static final int NF_NETLINK_CONNTRACK_NEW = 1;
    public static final int NF_NETLINK_CONNTRACK_UPDATE = 2;
    public static final int NF_NETLINK_CONNTRACK_DESTROY = 4;

    /**
     * A class for describing parsed netfilter conntrack events.
     */
    public static class ConntrackEvent { /*TODO*/ }

    /**
     * A callback to caller for conntrack event.
     */
    public interface ConntrackEventConsumer {
        /**
         * Every conntrack event received on the netlink socket is passed in
         * here.
         */
        void accept(@NonNull ConntrackEvent event);
    }

    private final ConntrackEventConsumer mConsumer;

    public ConntrackMonitor(@NonNull Handler h, @NonNull SharedLog log,
            @NonNull ConntrackEventConsumer cb) {
        super(h, log, TAG, OsConstants.NETLINK_NETFILTER, NF_NETLINK_CONNTRACK_NEW
                | NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY);
        mConsumer = cb;
    }

    @Override
    public void processNetlinkMessage(NetlinkMessage nlMsg, final long whenMs) {
        if (!(nlMsg instanceof ConntrackMessage)) {
            mLog.e("non-conntrack msg: " + nlMsg);
            return;
        }

        mConsumer.accept(new ConntrackEvent() /* TODO */);
    }
}
+23 −4
Original line number Diff line number Diff line
@@ -39,9 +39,6 @@ import java.nio.ByteOrder;
public class ConntrackMessage extends NetlinkMessage {
    public static final int STRUCT_SIZE = StructNlMsgHdr.STRUCT_SIZE + StructNfGenMsg.STRUCT_SIZE;

    public static final short NFNL_SUBSYS_CTNETLINK = 1;
    public static final short IPCTNL_MSG_CT_NEW = 0;

    // enum ctattr_type
    public static final short CTA_TUPLE_ORIG  = 1;
    public static final short CTA_TUPLE_REPLY = 2;
@@ -84,7 +81,8 @@ public class ConntrackMessage extends NetlinkMessage {

        final ConntrackMessage ctmsg = new ConntrackMessage();
        ctmsg.mHeader.nlmsg_len = bytes.length;
        ctmsg.mHeader.nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_NEW;
        ctmsg.mHeader.nlmsg_type = (NetlinkConstants.NFNL_SUBSYS_CTNETLINK << 8)
                | NetlinkConstants.IPCTNL_MSG_CT_NEW;
        ctmsg.mHeader.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_REPLACE;
        ctmsg.mHeader.nlmsg_seq = 1;
        ctmsg.pack(byteBuffer);
@@ -95,6 +93,22 @@ public class ConntrackMessage extends NetlinkMessage {
        return bytes;
    }

    /**
     * Parses a netfilter conntrack message from a {@link ByteBuffer}.
     *
     * @param header the netlink message header.
     * @param byteBuffer The buffer from which to parse the netfilter conntrack message.
     * @return the parsed netfilter conntrack message, or {@code null} if the netfilter conntrack
     *         message could not be parsed successfully (for example, if it was truncated).
     */
    public static ConntrackMessage parse(StructNlMsgHdr header, ByteBuffer byteBuffer) {
        // Just build the netlink header for now and pretend the whole message was consumed.
        // TODO: Parse the netfilter message header and conntrack attributes.
        final ConntrackMessage conntrackMsg = new ConntrackMessage(header);
        byteBuffer.position(byteBuffer.limit());
        return conntrackMsg;
    }

    protected StructNfGenMsg mNfGenMsg;

    private ConntrackMessage() {
@@ -102,6 +116,11 @@ public class ConntrackMessage extends NetlinkMessage {
        mNfGenMsg = new StructNfGenMsg((byte) OsConstants.AF_INET);
    }

    private ConntrackMessage(StructNlMsgHdr header) {
        super(header);
        mNfGenMsg = null;
    }

    public void pack(ByteBuffer byteBuffer) {
        mHeader.pack(byteBuffer);
        mNfGenMsg.pack(byteBuffer);
+68 −27
Original line number Diff line number Diff line
@@ -27,8 +27,10 @@ import java.nio.ByteBuffer;
 *
 * Values taken from:
 *
 *     &lt;linux_src&gt;/include/uapi/linux/netlink.h
 *     &lt;linux_src&gt;/include/uapi/linux/rtnetlink.h
 *     include/uapi/linux/netfilter/nfnetlink.h
 *     include/uapi/linux/netfilter/nfnetlink_conntrack.h
 *     include/uapi/linux/netlink.h
 *     include/uapi/linux/rtnetlink.h
 *
 * @hide
 */
@@ -104,7 +106,21 @@ public class NetlinkConstants {
    public static final short RTM_GETRULE                   = 34;
    public static final short RTM_NEWNDUSEROPT              = 68;

    /* see &lt;linux_src&gt;/include/uapi/linux/sock_diag.h */
    // Netfilter netlink message types are presented by two bytes: high byte subsystem and
    // low byte operation. See the macro NFNL_SUBSYS_ID and NFNL_MSG_TYPE in
    // include/uapi/linux/netfilter/nfnetlink.h
    public static final short NFNL_SUBSYS_CTNETLINK         = 1;

    public static final short IPCTNL_MSG_CT_NEW             = 0;
    public static final short IPCTNL_MSG_CT_GET             = 1;
    public static final short IPCTNL_MSG_CT_DELETE          = 2;
    public static final short IPCTNL_MSG_CT_GET_CTRZERO     = 3;
    public static final short IPCTNL_MSG_CT_GET_STATS_CPU   = 4;
    public static final short IPCTNL_MSG_CT_GET_STATS       = 5;
    public static final short IPCTNL_MSG_CT_GET_DYING       = 6;
    public static final short IPCTNL_MSG_CT_GET_UNCONFIRMED = 7;

    /* see include/uapi/linux/sock_diag.h */
    public static final short SOCK_DIAG_BY_FAMILY = 20;

    // Netlink groups.
@@ -163,6 +179,30 @@ public class NetlinkConstants {
        }
    }

    /**
     * Convert a netlink message type to a string for NETLINK_NETFILTER.
     */
    @NonNull
    private static String stringForNfMsgType(short nlmType) {
        final byte subsysId = (byte) (nlmType >> 8);
        final byte msgType = (byte) nlmType;
        switch (subsysId) {
            case NFNL_SUBSYS_CTNETLINK:
                switch (msgType) {
                    case IPCTNL_MSG_CT_NEW: return "IPCTNL_MSG_CT_NEW";
                    case IPCTNL_MSG_CT_GET: return "IPCTNL_MSG_CT_GET";
                    case IPCTNL_MSG_CT_DELETE: return "IPCTNL_MSG_CT_DELETE";
                    case IPCTNL_MSG_CT_GET_CTRZERO: return "IPCTNL_MSG_CT_GET_CTRZERO";
                    case IPCTNL_MSG_CT_GET_STATS_CPU: return "IPCTNL_MSG_CT_GET_STATS_CPU";
                    case IPCTNL_MSG_CT_GET_STATS: return "IPCTNL_MSG_CT_GET_STATS";
                    case IPCTNL_MSG_CT_GET_DYING: return "IPCTNL_MSG_CT_GET_DYING";
                    case IPCTNL_MSG_CT_GET_UNCONFIRMED: return "IPCTNL_MSG_CT_GET_UNCONFIRMED";
                }
                break;
        }
        return "unknown NETFILTER type: " + String.valueOf(nlmType);
    }

    /**
     * Convert a netlink message type to a string by netlink family.
     */
@@ -177,6 +217,7 @@ public class NetlinkConstants {
        // not constant.
        if (nlFamily == OsConstants.NETLINK_ROUTE) return stringForRtMsgType(nlmType);
        if (nlFamily == OsConstants.NETLINK_INET_DIAG) return stringForInetDiagMsgType(nlmType);
        if (nlFamily == OsConstants.NETLINK_NETFILTER) return stringForNfMsgType(nlmType);

        return "unknown type: " + String.valueOf(nlmType);
    }
+16 −0
Original line number Diff line number Diff line
@@ -74,6 +74,9 @@ public class NetlinkMessage {
        if (nlFamily == OsConstants.NETLINK_INET_DIAG) {
            return parseInetDiagMessage(nlmsghdr, byteBuffer);
        }
        if (nlFamily == OsConstants.NETLINK_NETFILTER) {
            return parseNfMessage(nlmsghdr, byteBuffer);
        }

        return null;
    }
@@ -136,4 +139,17 @@ public class NetlinkMessage {
            default: return null;
        }
    }

    @Nullable
    private static NetlinkMessage parseNfMessage(@NonNull StructNlMsgHdr nlmsghdr,
            @NonNull ByteBuffer byteBuffer) {
        switch (nlmsghdr.nlmsg_type) {
            case NetlinkConstants.NFNL_SUBSYS_CTNETLINK << 8
                    | NetlinkConstants.IPCTNL_MSG_CT_NEW:
            case NetlinkConstants.NFNL_SUBSYS_CTNETLINK << 8
                    | NetlinkConstants.IPCTNL_MSG_CT_DELETE:
                return (NetlinkMessage) ConntrackMessage.parse(nlmsghdr, byteBuffer);
            default: return null;
        }
    }
}