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