Home | History | Annotate | Download | only in net
      1 //
      2 // Copyright (C) 2012 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #ifndef SHILL_NET_RTNL_HANDLER_H_
     18 #define SHILL_NET_RTNL_HANDLER_H_
     19 
     20 #include <memory>
     21 #include <set>
     22 #include <string>
     23 #include <vector>
     24 
     25 #include <base/callback.h>
     26 #include <base/lazy_instance.h>
     27 #include <base/memory/ref_counted.h>
     28 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
     29 
     30 #include "shill/net/io_handler_factory_container.h"
     31 #include "shill/net/rtnl_listener.h"
     32 #include "shill/net/rtnl_message.h"
     33 #include "shill/net/shill_export.h"
     34 
     35 namespace shill {
     36 
     37 class Sockets;
     38 
     39 // This singleton class is responsible for interacting with the RTNL subsystem.
     40 // RTNL provides (among other things) access to interface discovery (add/remove
     41 // events), interface state monitoring and the ability to change interace flags.
     42 // Similar functionality also exists for IP address configuration for interfaces
     43 // and IP routing tables.
     44 //
     45 // RTNLHandler provides access to these events through a callback system and
     46 // provides utility functions to make changes to interface, address and routing
     47 // state.
     48 class SHILL_EXPORT RTNLHandler {
     49  public:
     50   // Request mask.
     51   static const int kRequestLink = 1;
     52   static const int kRequestAddr = 2;
     53   static const int kRequestRoute = 4;
     54   static const int kRequestRdnss = 8;
     55   static const int kRequestNeighbor = 16;
     56   static const int kRequestBridgeNeighbor = 32;
     57 
     58   typedef std::set<int> ErrorMask;
     59 
     60   virtual ~RTNLHandler();
     61 
     62   // Since this is a singleton, use RTNHandler::GetInstance()->Foo().
     63   static RTNLHandler* GetInstance();
     64 
     65   // This starts the event-monitoring function of the RTNL handler. This
     66   // function will create an IOHandler and add it to the current message
     67   // loop.
     68   virtual void Start(uint32_t netlink_groups_mask);
     69 
     70   // Add an RTNL event listener to the list of entities that will
     71   // be notified of RTNL events.
     72   virtual void AddListener(RTNLListener* to_add);
     73 
     74   // Remove a previously added RTNL event listener
     75   virtual void RemoveListener(RTNLListener* to_remove);
     76 
     77   // Set flags on a network interface that has a kernel index of
     78   // 'interface_index'.  Only the flags bits set in 'change' will
     79   // be set, and they will be set to the corresponding bit in 'flags'.
     80   virtual void SetInterfaceFlags(int interface_index,
     81                                  unsigned int flags,
     82                                  unsigned int change);
     83 
     84   // Set the maximum transmission unit (MTU) for the network interface that
     85   // has a kernel index of |interface_index|.
     86   virtual void SetInterfaceMTU(int interface_index, unsigned int mtu);
     87 
     88   // Set address of a network interface that has a kernel index of
     89   // 'interface_index'.
     90   virtual bool AddInterfaceAddress(int interface_index,
     91                                    const IPAddress& local,
     92                                    const IPAddress& gateway,
     93                                    const IPAddress& peer);
     94 
     95   // Remove address from a network interface that has a kernel index of
     96   // 'interface_index'.
     97   virtual bool RemoveInterfaceAddress(int interface_index,
     98                                       const IPAddress& local);
     99 
    100   // Remove a network interface from the kernel.
    101   virtual bool RemoveInterface(int interface_index);
    102 
    103   // Request that various tables (link, address, routing) tables be
    104   // exhaustively dumped via RTNL.  As results arrive from the kernel
    105   // they will be broadcast to all listeners.  The possible values
    106   // (multiple can be ORred together) are below.
    107   virtual void RequestDump(int request_flags);
    108 
    109   // Returns the index of interface |interface_name|, or -1 if unable to
    110   // determine the index.
    111   virtual int GetInterfaceIndex(const std::string& interface_name);
    112 
    113   // Send a formatted RTNL message.  Associates an error mask -- a list
    114   // of errors that are expected and should not trigger log messages by
    115   // default -- with the outgoing message.  If the message is sent
    116   // successfully, the sequence number in |message| is set, and the
    117   // function returns true.  Otherwise this function returns false.
    118   virtual bool SendMessageWithErrorMask(RTNLMessage* message,
    119                                         const ErrorMask& error_mask);
    120 
    121   // Sends a formatted RTNL message using SendMessageWithErrorMask
    122   // using an error mask inferred from the mode and type of |message|.
    123   virtual bool SendMessage(RTNLMessage* message);
    124 
    125  protected:
    126   RTNLHandler();
    127 
    128  private:
    129   friend struct base::DefaultLazyInstanceTraits<RTNLHandler>;
    130   friend class CellularTest;
    131   friend class DeviceInfoTest;
    132   friend class ModemTest;
    133   friend class RTNLHandlerTest;
    134   friend class RTNLListenerTest;
    135   friend class RoutingTableTest;
    136 
    137   FRIEND_TEST(RTNLListenerTest, NoRun);
    138   FRIEND_TEST(RTNLListenerTest, Run);
    139   FRIEND_TEST(RoutingTableTest, RouteDeleteForeign);
    140 
    141   static const int kReceiveBufferSize;
    142   static const int kInvalidSocket;
    143 
    144   // Size of the window for receiving error sequences out-of-order.
    145   static const int kErrorWindowSize;
    146 
    147   // This stops the event-monitoring function of the RTNL handler -- it is
    148   // private since it will never happen in normal running, but is useful for
    149   // tests.
    150   void Stop();
    151 
    152   // Dispatches an rtnl message to all listeners
    153   void DispatchEvent(int type, const RTNLMessage& msg);
    154   // Send the next table-dump request to the kernel
    155   void NextRequest(uint32_t seq);
    156   // Parse an incoming rtnl message from the kernel
    157   void ParseRTNL(InputData* data);
    158 
    159   bool AddressRequest(int interface_index,
    160                       RTNLMessage::Mode mode,
    161                       int flags,
    162                       const IPAddress& local,
    163                       const IPAddress& gateway,
    164                       const IPAddress& peer);
    165 
    166   // Called by the RTNL read handler on exceptional events.
    167   void OnReadError(const std::string& error_msg);
    168 
    169   // Returns whether |sequence| lies within the current error mask window.
    170   bool IsSequenceInErrorMaskWindow(uint32_t sequence);
    171 
    172   // Saves an error mask to be associated with this sequence number.
    173   void SetErrorMask(uint32_t sequence, const ErrorMask& error_mask);
    174 
    175   // Destructively retrieves the error mask associated with this sequeunce
    176   // number.  If this sequence number now lies outside the receive window
    177   // or no error mask was assigned, an empty ErrorMask is returned.
    178   ErrorMask GetAndClearErrorMask(uint32_t sequence);
    179 
    180   std::unique_ptr<Sockets> sockets_;
    181   bool in_request_;
    182 
    183   int rtnl_socket_;
    184   uint32_t request_flags_;
    185   uint32_t request_sequence_;
    186   uint32_t last_dump_sequence_;
    187 
    188   std::vector<RTNLListener*> listeners_;
    189   base::Callback<void(InputData*)> rtnl_callback_;
    190   std::unique_ptr<IOHandler> rtnl_handler_;
    191   IOHandlerFactory* io_handler_factory_;
    192   std::vector<ErrorMask> error_mask_window_;
    193 
    194   DISALLOW_COPY_AND_ASSIGN(RTNLHandler);
    195 };
    196 
    197 }  // namespace shill
    198 
    199 #endif  // SHILL_NET_RTNL_HANDLER_H_
    200