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

Commit 3716068c authored by Niranjan Pendharkar's avatar Niranjan Pendharkar Committed by Steve Kondik
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: I5e50185c9ac1cf72c9366815c2ecf590842edfca
parent decbe1a6
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.
@@ -367,4 +371,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.
@@ -52,6 +56,7 @@ import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
import android.util.SparseBooleanArray;
@@ -72,10 +77,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;
@@ -115,6 +122,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
        public static final int TetherDnsFwdTgtListResult = 112;
        public static final int TtyListResult             = 113;

        public static final int CommandOkay               = 200;
        public static final int TetherStatusResult        = 210;
        public static final int IpFwdStatusResult         = 211;
        public static final int InterfaceGetCfgResult     = 213;
@@ -1559,4 +1567,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;
    }
}