/* * This file is open source software, licensed to you under the terms * of the Apache License, Version 2.0 (the "License"). See the NOTICE file * distributed with this work for additional information regarding copyright * ownership. You may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* * Copyright (C) 2014 Cloudius Systems, Ltd. */ #ifndef CEPH_MSG_DPDK_NET_H #define CEPH_MSG_DPDK_NET_H #include "const.h" #include "ethernet.h" #include "Packet.h" #include "stream.h" #include "toeplitz.h" struct hw_features { // Enable tx ip header checksum offload bool tx_csum_ip_offload = false; // Enable tx l4 (TCP or UDP) checksum offload bool tx_csum_l4_offload = false; // Enable rx checksum offload bool rx_csum_offload = false; // LRO is enabled bool rx_lro = false; // Enable tx TCP segment offload bool tx_tso = false; // Enable tx UDP fragmentation offload bool tx_ufo = false; // Maximum Transmission Unit uint16_t mtu = 1500; // Maximun packet len when TCP/UDP offload is enabled uint16_t max_packet_len = ip_packet_len_max - eth_hdr_len; }; class forward_hash { uint8_t data[64]; size_t end_idx = 0; public: size_t size() const { return end_idx; } void push_back(uint8_t b) { ceph_assert(end_idx < sizeof(data)); data[end_idx++] = b; } void push_back(uint16_t b) { push_back(uint8_t(b)); push_back(uint8_t(b >> 8)); } void push_back(uint32_t b) { push_back(uint16_t(b)); push_back(uint16_t(b >> 16)); } const uint8_t& operator[](size_t idx) const { return data[idx]; } }; class interface; class l3_protocol { public: struct l3packet { eth_protocol_num proto_num; ethernet_address to; Packet p; }; using packet_provider_type = std::function ()>; private: interface* _netif; eth_protocol_num _proto_num; public: explicit l3_protocol(interface* netif, eth_protocol_num proto_num, packet_provider_type func); subscription receive( std::function rx_fn, std::function forward); private: friend class interface; }; class DPDKDevice; struct ipv4_address; class interface { CephContext *cct; struct l3_rx_stream { stream packet_stream; std::function forward; bool ready() { return packet_stream.started(); } explicit l3_rx_stream(std::function&& fw) : forward(fw) {} }; std::unordered_map _proto_map; std::shared_ptr _dev; subscription _rx; ethernet_address _hw_address; struct hw_features _hw_features; std::vector _pkt_providers; private: int dispatch_packet(EventCenter *c, Packet p); public: explicit interface(CephContext *cct, std::shared_ptr dev, EventCenter *center); ethernet_address hw_address() { return _hw_address; } const struct hw_features& get_hw_features() const { return _hw_features; } subscription register_l3( eth_protocol_num proto_num, std::function next, std::function forward); void forward(EventCenter *source, unsigned target, Packet p); unsigned hash2cpu(uint32_t hash); void register_packet_provider(l3_protocol::packet_provider_type func) { _pkt_providers.push_back(std::move(func)); } const rss_key_type& rss_key() const; uint16_t hw_queues_count() const; void arp_learn(ethernet_address l2, ipv4_address l3); friend class l3_protocol; }; #endif //CEPH_MSG_DPDK_NET_H