bmv2
Designing your own switch target with bmv2
dev_mgr.h
Go to the documentation of this file.
1 /* Copyright 2013-present Barefoot Networks, Inc.
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 /*
17  * Antonin Bas (antonin@barefootnetworks.com)
18  *
19  */
20 
34 
35 #ifndef BM_BM_SIM_DEV_MGR_H_
36 #define BM_BM_SIM_DEV_MGR_H_
37 
38 #include <bm/config.h>
39 
40 #include <functional>
41 #include <map>
42 #include <memory>
43 #include <string>
44 
45 #include "packet_handler.h"
46 #include "port_monitor.h"
47 
48 namespace bm {
49 
50 class DevMgrIface : public PacketDispatcherIface {
51  public:
53  using PortStatus = PortMonitorIface::PortStatus;
54  using PortStatusCb = PortMonitorIface::PortStatusCb;
55  using PortExtras = std::map<std::string, std::string>;
56 
57  static constexpr char kPortExtraInPcap[] = "in_pcap";
58  static constexpr char kPortExtraOutPcap[] = "out_pcap";
59 
60  struct PortInfo {
61  PortInfo(port_t port_num, const std::string &iface_name,
62  const PortExtras &port_extras = {})
63  : port_num(port_num), iface_name(iface_name), extra(port_extras) { }
64 
65  void set_is_up(bool status) {
66  is_up = status;
67  }
68 
69  void add_extra(const std::string &key, const std::string &value) {
70  extra.emplace(key, value);
71  }
72 
73  port_t port_num{};
74  std::string iface_name{};
75  bool is_up{true};
76  PortExtras extra{};
77  };
78 
79  struct PortStats {
80  uint64_t in_packets;
81  uint64_t in_octets;
82  uint64_t out_packets;
83  uint64_t out_octets;
84 
85  static PortStats make(uint64_t in_packets, uint64_t in_octets,
86  uint64_t out_packets, uint64_t out_octets) {
87  return {in_packets, in_octets, out_packets, out_octets};
88  }
89  };
90 
91  virtual ~DevMgrIface();
92 
93  ReturnCode port_add(const std::string &iface_name, port_t port_num,
94  const PortExtras &port_extras);
95 
96  ReturnCode port_remove(port_t port_num);
97 
98  // TODO(antonin): add this?
99  // ReturnCode set_port_status(port_t port_num, PortStatus status);
100 
101  void transmit_fn(port_t port_num, const char *buffer, int len) {
102  transmit_fn_(port_num, buffer, len);
103  }
104 
105  // start the thread that performs packet processing
106  void start();
107 
108  ReturnCode set_packet_handler(const PacketHandler &handler, void *cookie);
109 
110  bool port_is_up(port_t port_num) const;
111 
112  ReturnCode register_status_cb(const PortStatus &type,
113  const PortStatusCb &port_cb);
114 
115  std::map<port_t, PortInfo> get_port_info() const;
116 
117  PortStats get_port_stats(port_t port) const;
118  // clear and return stats (before clear)
119  PortStats clear_port_stats(port_t port);
120 
121  protected:
122  std::unique_ptr<PortMonitorIface> p_monitor{nullptr};
123 
124  private:
125  virtual ReturnCode port_add_(const std::string &iface_name, port_t port_num,
126  const PortExtras &port_extras) = 0;
127 
128  virtual ReturnCode port_remove_(port_t port_num) = 0;
129 
130  virtual void transmit_fn_(port_t port_num, const char *buffer, int len) = 0;
131 
132  virtual void start_() = 0;
133 
134  virtual ReturnCode set_packet_handler_(const PacketHandler &handler,
135  void *cookie) = 0;
136 
137  virtual bool port_is_up_(port_t port_num) const = 0;
138 
139  virtual std::map<port_t, PortInfo> get_port_info_() const = 0;
140 
141  virtual PortStats get_port_stats_(port_t port) const;
142  virtual PortStats clear_port_stats_(port_t port);
143 };
144 
145 // TODO(antonin): should DevMgr and DevMgrIface somehow inherit from a common
146 // interface, or is it not worth the trouble?
147 
150 class DevMgr : public PacketDispatcherIface {
151  public:
158  using PortExtras = DevMgrIface::PortExtras;
159 
160  DevMgr();
161 
162  // set_dev_* : should be called before port_add and port_remove.
163 
164  // meant for testing
165  void set_dev_mgr(std::unique_ptr<DevMgrIface> my_pimp);
166 
167  void set_dev_mgr_bmi(
168  device_id_t device_id,
169  int max_port_count,
170  std::shared_ptr<TransportIface> notifications_transport = nullptr);
171 
172  // The interface names are instead interpreted as file names.
173  // wait_time_in_seconds indicate how long the starting thread should
174  // wait before starting to process packets.
175  void set_dev_mgr_files(unsigned wait_time_in_seconds);
176 
177 #ifdef BM_NANOMSG_ON
178  // if enforce ports is set to true, packets coming in on un-registered ports
179  // are dropped
180  void set_dev_mgr_packet_in(
181  device_id_t device_id, const std::string &addr,
182  std::shared_ptr<TransportIface> notifications_transport = nullptr,
183  bool enforce_ports = false);
184 #endif
185 
186  ReturnCode port_add(const std::string &iface_name, port_t port_num,
187  const PortExtras &port_extras);
188 
189  ReturnCode port_remove(port_t port_num);
190 
191  bool port_is_up(port_t port_num) const;
192 
193  std::map<port_t, DevMgrIface::PortInfo> get_port_info() const;
194 
195  DevMgrIface::PortStats get_port_stats(port_t port_num) const;
196  DevMgrIface::PortStats clear_port_stats(port_t port_num);
197 
199  void transmit_fn(port_t port_num, const char *buffer, int len);
200 
201  ReturnCode set_packet_handler(const PacketHandler &handler, void *cookie)
202  override;
203 
206  ReturnCode register_status_cb(const PortStatus &type,
207  const PortStatusCb &port_cb);
208 
209  // start the thread that performs packet processing
210  void start();
211 
212  DevMgr(const DevMgr &other) = delete;
213  DevMgr &operator=(const DevMgr &other) = delete;
214 
215  DevMgr(DevMgr &&other) = delete;
216  DevMgr &operator=(DevMgr &&other) = delete;
217 
218  protected:
219  ~DevMgr();
220 
221  std::string sample_packet_data(const char *buffer, int len);
222 
223  size_t dump_packet_data{0};
224 
225  int max_port_count;
226 
227  private:
228  // Actual implementation (private)
229  std::unique_ptr<DevMgrIface> pimp{nullptr};
230 };
231 
232 } // namespace bm
233 
234 #endif // BM_BM_SIM_DEV_MGR_H_
bm::DevMgr::register_status_cb
ReturnCode register_status_cb(const PortStatus &type, const PortStatusCb &port_cb)
bm::port_t
uint32_t port_t
Integral type used to identify a given port.
Definition: packet.h:53
bm::DevMgr::port_t
PortMonitorIface::port_t port_t
Representation of a port number.
Definition: dev_mgr.h:153
bm::DevMgr
Definition: dev_mgr.h:150
port_monitor.h
bm::PortMonitorIface::PortStatusCb
std::function< void(port_t port_num, const PortStatus status)> PortStatusCb
Signature of the cb function to call when a port status changes.
Definition: port_monitor.h:47
bm::PortMonitorIface::port_t
uint32_t port_t
Representation of a port number.
Definition: port_monitor.h:40
bm::PortMonitorIface::PortStatus
PortStatus
Represents the status of a port.
Definition: port_monitor.h:43
bm::DevMgr::transmit_fn
void transmit_fn(port_t port_num, const char *buffer, int len)
Transmits a data packet out of port port_num.
bm::DevMgr::PortStatusCb
PortMonitorIface::PortStatusCb PortStatusCb
Signature of the cb function to call when a port status changes.
Definition: dev_mgr.h:157