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
35namespace shill {
36
37class 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.
48class 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