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

Commit ae3b72d2 authored by Niranjan Pendharkar's avatar Niranjan Pendharkar Committed by Linux Build Service Account
Browse files

server: Add enhanced routing support

Add support for policy and metric based routing APIs to
NetworkManagementService. This functionality is used for WQE, IMS, and
Android QoS features.

Change-Id: I1789b60857060044ef09b9cd34d652ff9b852f84
(cherry picked from commit 257c24ea092c903dcb45a40796eb02d5681e053c)
(cherry picked from commit 9d4b173377181941dfe39137ae0bb33cd9469292)
(cherry picked from commit 5e5556837835152412a59a57e1362cd52ef89827)
(cherry picked from commit 01a74486c0e79e772f1b4a1149dc3c7a585a36f5)
parent 1ff419fc
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
/* //device/java/android/android/os/INetworkManagementService.aidl
**
** Copyright 2007, The Android Open Source Project
** Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
**
** Not a Contribution. Apache license notifications and license are
** retained for attribution purposes only.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -441,4 +445,27 @@ interface INetworkManagementService
     * Determine whether the clatd (464xlat) service has been started
     */
    boolean isClatdStarted();

   /**
    ** Policy Routing
    **/

   /**
    * Replaces a prexisting identical route with the new metric specified.
    * Adds a new route if none existed before.
    */
   boolean addRouteWithMetric(String iface, int metric, in RouteInfo route);

   /**
    * Replaces a source policy route for the given iface in a custom routing
    * table denoted by routeId, if it already exists.
    * Adds a new route if it did not exist.
    */
   boolean replaceSrcRoute(String iface, in byte[] ip, in byte[] gateway, int routeId);

   /**
    * Deletes a source policy route for the given route identifier and source
    * address from a custom routing table denoted by routeId
    */
   boolean delSrcRoute(in byte[] ip, int routeId);
}
+142 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2007 The Android Open Source Project
 * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
 *
 * Not a Contribution. Apache license notifications and license are
 * retained for attribution purposes only.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -54,6 +58,7 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
import android.util.SparseBooleanArray;
@@ -75,10 +80,12 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -120,6 +127,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
        public static final int TtyListResult             = 113;
        public static final int TetheringStatsListResult  = 114;

        public static final int CommandOkay               = 200;
        public static final int TetherStatusResult        = 210;
        public static final int IpFwdStatusResult         = 211;
        public static final int InterfaceGetCfgResult     = 213;
@@ -1773,4 +1781,138 @@ public class NetworkManagementService extends INetworkManagementService.Stub

        pw.print("Firewall enabled: "); pw.println(mFirewallEnabled);
    }

    @Override
    public boolean replaceSrcRoute(String iface, byte[] ip, byte[] gateway, int routeId) {
        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
        final NativeDaemonEvent rsp;
        InetAddress ipAddr;

        if (TextUtils.isEmpty(iface)) {
            Log.e(TAG,"route cmd failed - iface is invalid");
            return false;
        }

        try {
            ipAddr = InetAddress.getByAddress(ip);
        } catch (UnknownHostException e) {
            Log.e(TAG,"route cmd failed because of unknown src ip", e);
            return false;
        }

        final Command cmd = new Command("route", "replace", "src");

        if (ipAddr instanceof Inet4Address)
            cmd.appendArg("v4");
        else
            cmd.appendArg("v6");

        cmd.appendArg(iface);
        cmd.appendArg(ipAddr.getHostAddress());
        cmd.appendArg(routeId);

        try {
            InetAddress gatewayAddr = InetAddress.getByAddress(gateway);
            // check validity of gw address - add route without gw if its invalid
            if ((ipAddr instanceof Inet4Address && gatewayAddr instanceof Inet4Address) ||
                    (ipAddr instanceof Inet6Address && gatewayAddr instanceof Inet6Address))
            {
                cmd.appendArg(gatewayAddr.getHostAddress());
            }
        } catch (UnknownHostException e) {
            Log.w(TAG,"route cmd did not obtain valid gw; adding route without gw");
        }

        try {
            rsp = mConnector.execute(cmd);
        } catch (NativeDaemonConnectorException e) {
            Log.w(TAG,"route cmd failed: ", e);
            return false;
        }
        if (DBG) {
            Slog.v(TAG, "replace src route response is " + rsp.toString());
        }
        return true;
    }

    @Override
    public boolean delSrcRoute(byte[] ip, int routeId) {
        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
        final NativeDaemonEvent rsp;
        InetAddress ipAddr;

        try {
            ipAddr = InetAddress.getByAddress(ip);
        } catch (UnknownHostException e) {
            Log.e(TAG,"route cmd failed due to invalid src ip", e);
            return false; //cannot remove src route without valid src prefix
        }

        final Command cmd = new Command("route", "del", "src");

        if (ipAddr instanceof Inet4Address) {
            cmd.appendArg("v4");
        } else {
            cmd.appendArg("v6");
        }

        cmd.appendArg(routeId);

        try {
            rsp = mConnector.execute(cmd);
        } catch (NativeDaemonConnectorException e) {
            Log.w(TAG,"route cmd failed: ", e);
            return false;
        }
        if (DBG) {
            Slog.v(TAG, "del src route response is " + rsp.toString());
        }
        return true;
    }

    @Override
    public boolean addRouteWithMetric(String iface, int metric, RouteInfo route) {
        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
        final NativeDaemonEvent rsp;

        if (TextUtils.isEmpty(iface)) {
            Log.e(TAG,"route cmd failed - iface is invalid");
            return false;
        }

        final Command cmd = new Command("route", "add");
        if (route.isDefaultRoute()) {
            cmd.appendArg("def");
        } else {
            cmd.appendArg("dst");
        }

        InetAddress gateway = route.getGateway();
        if (gateway instanceof Inet4Address) {
            cmd.appendArg("v4");
        } else {
            cmd.appendArg("v6");
        }

        cmd.appendArg(iface);
        cmd.appendArg(metric);

        if (route.isHostRoute()) {
            cmd.appendArg(route.getDestination().getAddress().getHostAddress());
        }

        cmd.appendArg(gateway.getHostAddress());

        try {
            rsp = mConnector.execute(cmd);
        } catch (NativeDaemonConnectorException e) {
            Log.w(TAG,"route cmd failed: ", e);
            return false;
        }

        if (DBG) {
            Slog.v(TAG, "add metric route response is " + rsp.toString());
        }
        return true;
    }
}