Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / msg / async / dpdk / net.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 /*
3  * Ceph - scalable distributed file system
4  *
5  * Copyright (C) 2015 XSky <haomai@xsky.com>
6  *
7  * Author: Haomai Wang <haomaiwang@gmail.com>
8  *
9  * This is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License version 2.1, as published by the Free Software
12  * Foundation.  See file COPYING.
13  *
14  */
15 #ifndef CEPH_MSG_DPDK_NET_H
16 #define CEPH_MSG_DPDK_NET_H
17
18 #include "const.h"
19 #include "ethernet.h"
20 #include "Packet.h"
21 #include "stream.h"
22 #include "toeplitz.h"
23
24 struct hw_features {
25   // Enable tx ip header checksum offload
26   bool tx_csum_ip_offload = false;
27   // Enable tx l4 (TCP or UDP) checksum offload
28   bool tx_csum_l4_offload = false;
29   // Enable rx checksum offload
30   bool rx_csum_offload = false;
31   // LRO is enabled
32   bool rx_lro = false;
33   // Enable tx TCP segment offload
34   bool tx_tso = false;
35   // Enable tx UDP fragmentation offload
36   bool tx_ufo = false;
37   // Maximum Transmission Unit
38   uint16_t mtu = 1500;
39   // Maximun packet len when TCP/UDP offload is enabled
40   uint16_t max_packet_len = ip_packet_len_max - eth_hdr_len;
41 };
42
43 class forward_hash {
44   uint8_t data[64];
45   size_t end_idx = 0;
46  public:
47   size_t size() const {
48     return end_idx;
49   }
50   void push_back(uint8_t b) {
51     assert(end_idx < sizeof(data));
52     data[end_idx++] = b;
53   }
54   void push_back(uint16_t b) {
55     push_back(uint8_t(b));
56     push_back(uint8_t(b >> 8));
57   }
58   void push_back(uint32_t b) {
59     push_back(uint16_t(b));
60     push_back(uint16_t(b >> 16));
61   }
62   const uint8_t& operator[](size_t idx) const {
63     return data[idx];
64   }
65 };
66
67 class interface;
68
69 class l3_protocol {
70  public:
71   struct l3packet {
72     eth_protocol_num proto_num;
73     ethernet_address to;
74     Packet p;
75   };
76   using packet_provider_type = std::function<Tub<l3packet> ()>;
77
78  private:
79   interface* _netif;
80   eth_protocol_num _proto_num;
81
82  public:
83   explicit l3_protocol(interface* netif, eth_protocol_num proto_num, packet_provider_type func);
84   subscription<Packet, ethernet_address> receive(
85       std::function<int (Packet, ethernet_address)> rx_fn,
86       std::function<bool (forward_hash &h, Packet &p, size_t s)> forward);
87
88  private:
89   friend class interface;
90 };
91
92 class DPDKDevice;
93 struct ipv4_address;
94
95 class interface {
96   CephContext *cct;
97   struct l3_rx_stream {
98     stream<Packet, ethernet_address> packet_stream;
99     std::function<bool (forward_hash&, Packet&, size_t)> forward;
100     bool ready() { return packet_stream.started(); }
101     l3_rx_stream(std::function<bool (forward_hash&, Packet&, size_t)>&& fw) : forward(fw) {}
102   };
103   std::unordered_map<uint16_t, l3_rx_stream> _proto_map;
104   std::shared_ptr<DPDKDevice> _dev;
105   subscription<Packet> _rx;
106   ethernet_address _hw_address;
107   struct hw_features _hw_features;
108   std::vector<l3_protocol::packet_provider_type> _pkt_providers;
109
110  private:
111   int dispatch_packet(EventCenter *c, Packet p);
112  public:
113   explicit interface(CephContext *cct, std::shared_ptr<DPDKDevice> dev, EventCenter *c);
114   ethernet_address hw_address() { return _hw_address; }
115   const struct hw_features& get_hw_features() const { return _hw_features; }
116   subscription<Packet, ethernet_address> register_l3(
117       eth_protocol_num proto_num,
118       std::function<int (Packet, ethernet_address)> next,
119       std::function<bool (forward_hash&, Packet&, size_t)> forward);
120   void forward(EventCenter *source, unsigned target, Packet p);
121   unsigned hash2cpu(uint32_t hash);
122   void register_packet_provider(l3_protocol::packet_provider_type func) {
123     _pkt_providers.push_back(std::move(func));
124   }
125   const rss_key_type& rss_key() const;
126   uint16_t hw_queues_count() const;
127   void arp_learn(ethernet_address l2, ipv4_address l3);
128   friend class l3_protocol;
129 };
130
131 #endif //CEPH_MSG_DPDK_NET_H