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