Home | History | Annotate | Download | only in inc
      1 /*
      2  * Copyright (c) 2017, The Linux Foundation. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *    * Redistributions of source code must retain the above copyright
      8  *      notice, this list of conditions and the following disclaimer.
      9  *    * Redistributions in binary form must reproduce the above
     10  *      copyright notice, this list of conditions and the following
     11  *      disclaimer in the documentation and/or other materials provided
     12  *      with the distribution.
     13  *    * Neither the name of The Linux Foundation nor the names of its
     14  *      contributors may be used to endorse or promote products derived
     15  *      from this software without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     18  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     24  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     26  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     27  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 #ifndef _I_OFFLOAD_MANAGER_H_
     30 #define _I_OFFLOAD_MANAGER_H_
     31 
     32 /* External Includes */
     33 #include <sys/types.h>
     34 
     35 /* Internal Includes */
     36 #include "OffloadStatistics.h"
     37 
     38 
     39 class IOffloadManager {
     40 public:
     41     enum RET {
     42         FAIL_TOO_MANY_PREFIXES = -6,
     43         FAIL_UNSUPPORTED = -5,
     44         FAIL_INPUT_CHECK = -4,
     45         FAIL_HARDWARE = -3,
     46         FAIL_UNNEEDED = -2,
     47         FAIL_TRY_AGAIN = -1,
     48         SUCCESS = 0,
     49         SUCCESS_DUPLICATE_CONFIG = 1,
     50         SUCCESS_NO_OP = 2,
     51         SUCCESS_OPTIMIZED = 3
     52     }; /* RET */
     53 
     54     enum IP_FAM {
     55         V4 = 0,
     56         V6 = 1,
     57         INVALID = 2
     58     }; /* IP_FAM */
     59 
     60     /* Overloading to use for addresses as well */
     61     typedef struct Prefix {
     62         IP_FAM fam;
     63         uint32_t v4Addr;
     64         uint32_t v4Mask;
     65         uint32_t v6Addr[4];
     66         uint32_t v6Mask[4];
     67     } prefix_t;
     68 
     69     /* ---------------------------- LIFECYCLE ------------------------------- */
     70     virtual ~IOffloadManager(){}
     71 
     72     /* ---------------------- ASYNC EVENT CALLBACKS ------------------------- */
     73     class IpaEventListener {
     74     public:
     75         enum StoppedReason {
     76             /**
     77              * Offload was stopped due to the configuration being removed via
     78              * setUpstreamParameters/removeDownstream.
     79              */
     80             REQUESTED,
     81             /**
     82              * Offload was stopped due to an internal (to IPA or modem) error.
     83              *
     84              * Statistics may be temporarily unavailable.
     85              */
     86             ERROR,
     87             /**
     88              * Offload was stopped because the upstream connection has
     89              * migrated to unsupported radio access technology.
     90              *
     91              * Statistics will still be available.
     92              */
     93             UNSUPPORTED
     94         }; /* StoppedReason */
     95         virtual ~IpaEventListener(){}
     96         /**
     97          * Called when Offload first begins to occur on any upstream and
     98          * tether interface pair.  It should be paired with an onOffloadStopped
     99          * call.
    100          */
    101         virtual void onOffloadStarted(){}
    102         /**
    103          * Called when Offload stops occurring on all upstream and tether
    104          * interface pairs.  It comes after a call to onOffloadStarted.
    105          *
    106          * @param reason Reason that Offload was stopped
    107          */
    108         virtual void onOffloadStopped(StoppedReason /* reason */){}
    109         /**
    110          * Called when the hardware can support Offload again.
    111          *
    112          * Any statistics that were previously unavailable, may be queried
    113          * again at this time.
    114          */
    115         virtual void onOffloadSupportAvailable(){}
    116         /**
    117          * Called when the limit set via setQuota has expired.
    118          *
    119          * It is implied that Offload has been stopped on all upstream and
    120          * tether interface pairs when this callback is called.
    121          */
    122         virtual void onLimitReached(){}
    123     }; /* IpaEventListener */
    124 
    125     /**
    126      * Request notifications about asynchronous events that occur in hardware.
    127      *
    128      * The calling client must be able to handle the callback on a separate
    129      * thread (i.e. their implementation of IpaEventListener must be thread
    130      * safe).
    131      *
    132      * @return SUCCESS iff callback successfully registered
    133      *
    134      * Remarks: This can't really be allowed to fail.
    135      */
    136     virtual RET registerEventListener(IpaEventListener* /* listener */) = 0;
    137     /**
    138      * Unregister a previously registered listener.
    139      *
    140      * @return SUCCESS iff callback successfully unregistered
    141      *         FAIL_INPUT_CHECK if callback was never registered
    142      */
    143     virtual RET unregisterEventListener(IpaEventListener* /* listener */) = 0;
    144 
    145     class ConntrackTimeoutUpdater {
    146     public:
    147         enum L4Protocol {
    148             TCP = 0,
    149             UDP = 1
    150         }; /* L4Protocol */
    151         typedef struct IpAddrPortPair {
    152             uint32_t ipAddr;
    153             uint16_t port;
    154         } ipAddrPortPair_t;
    155         typedef struct NatTimeoutUpdate {
    156             IpAddrPortPair src;
    157             IpAddrPortPair dst;
    158             L4Protocol proto;
    159         } natTimeoutUpdate_t;
    160         virtual ~ConntrackTimeoutUpdater(){}
    161         virtual void updateTimeout(NatTimeoutUpdate /* update */) {}
    162     }; /* ConntrackTimeoutUpdater */
    163 
    164     /**
    165      * Register a callback that may be called if the OffloadManager wants to
    166      * update the timeout value in conntrack of kernel.
    167      *
    168      * The calling client must be able to handle the callback on a separate
    169      * thread (i.e. their implementation of ConntrackTimeoutUpdater must be
    170      * thread safe)
    171      *
    172      * @return SUCCESS iff callback successfully registered
    173      *
    174      * Remarks: This can't really be allowed to fail
    175      */
    176     virtual RET registerCtTimeoutUpdater(ConntrackTimeoutUpdater* /* cb */) = 0;
    177     /**
    178      * Unregister a previously registered callback.
    179      *
    180      * @return SUCCESS iff callback successfully unregistered
    181      *         FAIL_INPUT_CHECK if callback was never registered
    182      */
    183     virtual RET unregisterCtTimeoutUpdater(ConntrackTimeoutUpdater* /* cb */) = 0;
    184 
    185     /* ----------------------------- CONFIG --------------------------------- */
    186     /**
    187      * Provide a file descriptor for use with conntrack library
    188      *
    189      * @param fd File Descriptor that has been opened and bound to groups
    190      * @param groups Groups (bit mask) that fd has been bound to
    191      *
    192      * @return SUCCESS iff IOffloadManager needed this file descriptor and
    193      *                 it was properly bound.
    194      *         FAIL_INPUT_CHECK if IOffloadManager needed this file descriptor
    195      *                          but it was found to not be properly bound
    196      *         FAIL_UNNEEDED if IOffloadManager determined that it does not need
    197      *                       a file descriptor bound to these groups.
    198      */
    199     virtual RET provideFd(int /* fd */, unsigned int /* group */) = 0;
    200     /**
    201      * Indicate that IOffloadManager <b>must</b> cease using all file
    202      * descriptors passed via provideFd API.
    203      *
    204      * After this call returns, the file descriptors will likely be closed by
    205      * the calling client.
    206      *
    207      * @return SUCCESS iff IOffloadManager has stopped using all file
    208      *                 descriptors
    209      *         FAIL_TRY_AGAIN if IOffloadManager needs more time with these
    210      *                        file descriptors before it can release them
    211      *
    212      * Remarks: Currently, it would be very difficult to handle a FAIL_TRY_AGAIN
    213      *          because HAL serivce does not own a thread outside of RPC
    214      *          Threadpool to reschedule this call.
    215      */
    216     virtual RET clearAllFds() = 0;
    217     /**
    218      * Query whether STA+AP offload is supported on this device.
    219      *
    220      * @return true if supported, false otherwise
    221      */
    222     virtual bool isStaApSupported() = 0;
    223 
    224     /* ------------------------------ ROUTE --------------------------------- */
    225     /**
    226      * Add a downstream prefix that <i>may</i> be forwarded.
    227      *
    228      * The Prefix may be an IPv4 or IPv6 address to signify which family can be
    229      * offloaded from the specified tether interface.  If the given IP family,
    230      * as determined by the Prefix, has a corresponding upstream configured,
    231      * then traffic should be forwarded between the two interfaces.
    232      *
    233      * Only traffic that has a downstream address within the specified Prefix
    234      * can be forwarded.  Traffic from the same downstream interface that falls
    235      * outside of the Prefix will be unaffected and can be forwarded iff it was
    236      * previously configured via a separate addDownstream call.
    237      *
    238      * If no upstream has been configured, then this information must be cached
    239      * so that offload may begin once an upstream is configured.
    240      *
    241      * This API does <b>not</b> replace any previously configured downstreams
    242      * and must be explicitly removed by calling removeDownstream or by clearing
    243      * the entire configuration by calling stopAllOffload.
    244      *
    245      * @return SUCCESS The new information was accepted
    246      *         FAIL_TOO_MANY_PREFIXES The hardware has already accepted the max
    247      *                                number of Prefixes that can be supported.
    248      *                                If offload is desired on this Prefix then
    249      *                                another must be removed first.
    250      *         FAIL_UNSUPPORTED The hardware cannot forward traffic from this
    251      *                          downstream interface and will never be able to.
    252      */
    253     virtual RET addDownstream(const char* /* downstream */,
    254             const Prefix& /* prefix */) = 0;
    255     /**
    256      * Remove a downstream Prefix that forwarding was previously requested for.
    257      *
    258      * The Prefix may be an IPv4 or IPv6 address.  Traffic outside of this
    259      * Prefix is not affected.
    260      *
    261      * @return SUCCESS iff forwarding was previously occurring and has been
    262      *                 stopped
    263      *         SUCCESS_NO_OP iff forwarding was not previously occurring and
    264      *                       therefore no action needed to be taken
    265      */
    266     virtual RET removeDownstream(const char* /* downstream */,
    267             const Prefix& /* prefix */) = 0;
    268     /**
    269      * Indicate that hardware should forward traffic from any configured
    270      * downstreams to the specified upstream.
    271      *
    272      * When iface is non-null and non-empty and v4Gw is valid, then any
    273      * currently configured or future configured IPv4 downstreams should be
    274      * forwarded to this upstream interface.
    275      *
    276      * When iface is non-null and non-empty and v6Gw is valid, then any
    277      * currently configured or future configured IPv6 downstreams should be
    278      * forwarded to this upstream interface.
    279      *
    280      * @param iface Upstream interface name.  Only one is needed because IPv4
    281      *              and IPv6 interface names are required to match.
    282      * @param v4Gw The address of the IPv4 Gateway on the iface
    283      * @param v6Gw The address of one of the IPv6 Gateways on the iface
    284      *
    285      * @return SUCCESS iff the specified configuration was applied
    286      *         SUCCESS_DUPLICATE_CONFIG if this configuration <i>exactly</i>
    287      *                                  matches a previously provided
    288      *                                  configuration.  This means that no
    289      *                                  action has to be taken, but, the
    290      *                                  configuration was previously accepted
    291      *                                  and applied.
    292      *         FAIL_UNSUPPORTED if hardware cannot support forwarding to this
    293      *                          upstream interface
    294      *
    295      * Remarks: This overrides any previously configured parameters
    296      */
    297     virtual RET setUpstream(const char* /* iface */, const Prefix& /* v4Gw */,
    298             const Prefix& /* v6Gw */) = 0;
    299     /**
    300      * All traffic must be returned to the software path and all configuration
    301      * (including provided file descriptors) must be forgotten.
    302      *
    303      * @return SUCCESS If all offload was successfully stopped and provided
    304      *                 file descriptors were released.
    305      *
    306      * Remarks: This can't really fail?
    307      */
    308     virtual RET stopAllOffload() = 0;
    309 
    310     /* --------------------------- STATS/POLICY ----------------------------- */
    311     /**
    312      * Instruct hardware to stop forwarding traffic and send a callback after
    313      * limit bytes have been transferred in either direction on this upstream
    314      * interface.
    315      *
    316      * @param upstream Upstream interface name that the limit should apply to
    317      * @param limit Bytes limit that can occur before action should be taken
    318      *
    319      * @return SUCCESS If the limit was successfully applied
    320      *         SUCCESS_OPTIMIZED If the limit was sufficiently high to be
    321      *                           interpreted as "no quota".
    322      *         FAIL_HARDWARE If the limit was rejected by the hardware
    323      *         FAIL_UNSUPPORTED If metering is not supported on this interface
    324      *         FAIL_TRY_AGAIN If this upstream has not been previously
    325      *                        configured to allow offload
    326      *                        (via setUpstreamParameters)
    327      */
    328     virtual RET setQuota(const char* /* upstream */, uint64_t /* limit */) = 0;
    329     /**
    330      * Query for statistics counters in hardware.
    331      *
    332      * This returns an aggregate of all hardware accelerated traffic which
    333      * has occurred on this upstream interface.
    334      *
    335      * @param upstream Interface on which traffic entered/exited
    336      * @param reset Whether hardware counters should reset after returning
    337      *              current statistics
    338      * @param ret Output variable where statistics are returned
    339      *
    340      * @return SUCCESS If the statistics were successfully populated in ret and
    341      *                 were successfully reset if requested.
    342      *         FAIL_TRY_AGAIN If the statistics are not currently available but
    343      *                        may be available later.  This may occur during
    344      *                        a subsystem restart.
    345      *         FAIL_UNSUPPORTED If statistics are not supported on this upstream
    346      */
    347     virtual RET getStats(const char* /* upstream */, bool /* reset */,
    348             OffloadStatistics& /* ret */) = 0;
    349 }; /* IOffloadManager */
    350 #endif /* _I_OFFLOAD_MANAGER_H_ */
    351