X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fmsg%2Fasync%2Fdpdk%2FIP.h;fp=src%2Fceph%2Fsrc%2Fmsg%2Fasync%2Fdpdk%2FIP.h;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=d5a4d305481f16287bb33a642c9f0627c0551998;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/src/msg/async/dpdk/IP.h b/src/ceph/src/msg/async/dpdk/IP.h deleted file mode 100644 index d5a4d30..0000000 --- a/src/ceph/src/msg/async/dpdk/IP.h +++ /dev/null @@ -1,427 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -/* - * 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. - * - */ -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2015 XSky - * - * Author: Haomai Wang - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software - * Foundation. See file COPYING. - * - */ - -#ifndef CEPH_MSG_IP_H_ -#define CEPH_MSG_IP_H_ - -#include -#include -#include -#include -#include -#include -#include - -#include "msg/async/Event.h" -#include "common/Throttle.h" - -#include "array_map.h" -#include "ARP.h" -#include "IPChecksum.h" -#include "ip_types.h" -#include "const.h" -#include "net.h" -#include "PacketUtil.h" -#include "toeplitz.h" - -class ipv4; -template -class ipv4_l4; - -template -class tcp; - -struct ipv4_traits { - using address_type = ipv4_address; - using inet_type = ipv4_l4; - struct l4packet { - ipv4_address to; - Packet p; - ethernet_address e_dst; - ip_protocol_num proto_num; - }; - using packet_provider_type = std::function ()>; - static void tcp_pseudo_header_checksum(checksummer& csum, ipv4_address src, ipv4_address dst, uint16_t len) { - csum.sum_many(src.ip, dst.ip, uint8_t(0), uint8_t(ip_protocol_num::tcp), len); - } - static constexpr uint8_t ip_hdr_len_min = ipv4_hdr_len_min; -}; - -template -class ipv4_l4 { - public: - ipv4& _inet; - public: - ipv4_l4(ipv4& inet) : _inet(inet) {} - void register_packet_provider(ipv4_traits::packet_provider_type func); - void wait_l2_dst_address(ipv4_address to, Packet p, resolution_cb cb); -}; - -class ip_protocol { - public: - virtual ~ip_protocol() {} - virtual void received(Packet p, ipv4_address from, ipv4_address to) = 0; - virtual bool forward(forward_hash& out_hash_data, Packet& p, size_t off) { return true; } -}; - -template -struct l4connid { - using ipaddr = typename InetTraits::address_type; - using inet_type = typename InetTraits::inet_type; - struct connid_hash; - - ipaddr local_ip; - ipaddr foreign_ip; - uint16_t local_port; - uint16_t foreign_port; - - bool operator==(const l4connid& x) const { - return local_ip == x.local_ip - && foreign_ip == x.foreign_ip - && local_port == x.local_port - && foreign_port == x.foreign_port; - } - - uint32_t hash(const rss_key_type& rss_key) { - forward_hash hash_data; - hash_data.push_back(hton(foreign_ip.ip)); - hash_data.push_back(hton(local_ip.ip)); - hash_data.push_back(hton(foreign_port)); - hash_data.push_back(hton(local_port)); - return toeplitz_hash(rss_key, hash_data); - } -}; - -class ipv4_tcp final : public ip_protocol { - ipv4_l4 _inet_l4; - std::unique_ptr> _tcp; - public: - ipv4_tcp(ipv4& inet, EventCenter *c); - ~ipv4_tcp(); - virtual void received(Packet p, ipv4_address from, ipv4_address to); - virtual bool forward(forward_hash& out_hash_data, Packet& p, size_t off) override; - friend class ipv4; -}; - -struct icmp_hdr { - enum class msg_type : uint8_t { - echo_reply = 0, - echo_request = 8, - }; - msg_type type; - uint8_t code; - uint16_t csum; - uint32_t rest; -} __attribute__((packed)); - - -class icmp { - public: - using ipaddr = ipv4_address; - using inet_type = ipv4_l4; - explicit icmp(CephContext *c, inet_type& inet) - : cct(c), _inet(inet), _queue_space(c, "DPDK::icmp::_queue_space", 212992) { - _inet.register_packet_provider([this] { - Tub l4p; - if (!_packetq.empty()) { - l4p = std::move(_packetq.front()); - _packetq.pop_front(); - _queue_space.put(l4p->p.len()); - } - return l4p; - }); - } - void received(Packet p, ipaddr from, ipaddr to); - - private: - CephContext *cct; - // ipv4_l4 - inet_type& _inet; - circular_buffer _packetq; - Throttle _queue_space; -}; - -class ipv4_icmp final : public ip_protocol { - CephContext *cct; - ipv4_l4 _inet_l4; - icmp _icmp; - public: - ipv4_icmp(CephContext *c, ipv4& inet) : cct(c), _inet_l4(inet), _icmp(c, _inet_l4) {} - virtual void received(Packet p, ipv4_address from, ipv4_address to) { - _icmp.received(std::move(p), from, to); - } - friend class ipv4; -}; - -struct ip_hdr; - -struct ip_packet_filter { - virtual ~ip_packet_filter() {}; - virtual void handle(Packet& p, ip_hdr* iph, ethernet_address from, bool & handled) = 0; -}; - -struct ipv4_frag_id { - struct hash; - ipv4_address src_ip; - ipv4_address dst_ip; - uint16_t identification; - uint8_t protocol; - bool operator==(const ipv4_frag_id& x) const { - return src_ip == x.src_ip && - dst_ip == x.dst_ip && - identification == x.identification && - protocol == x.protocol; - } -}; - -struct ipv4_frag_id::hash : private std::hash, - private std::hash, private std::hash { - size_t operator()(const ipv4_frag_id& id) const noexcept { - using h1 = std::hash; - using h2 = std::hash; - using h3 = std::hash; - return h1::operator()(id.src_ip) ^ - h1::operator()(id.dst_ip) ^ - h2::operator()(id.identification) ^ - h3::operator()(id.protocol); - } -}; - -struct ipv4_tag {}; -using ipv4_packet_merger = packet_merger; - -class interface; - -class ipv4 { - public: - using address_type = ipv4_address; - using proto_type = uint16_t; - static address_type broadcast_address() { return ipv4_address(0xffffffff); } - static proto_type arp_protocol_type() { return proto_type(eth_protocol_num::ipv4); } - CephContext *cct; - EventCenter *center; - - private: - interface* _netif; - std::vector _pkt_providers; - Tub frag_timefd; - EventCallbackRef frag_handler; - arp _global_arp; - arp_for _arp; - ipv4_address _host_address; - ipv4_address _gw_address; - ipv4_address _netmask; - l3_protocol _l3; - subscription _rx_packets; - ipv4_tcp _tcp; - ipv4_icmp _icmp; - array_map _l4; - ip_packet_filter *_packet_filter; - struct frag { - Packet header; - ipv4_packet_merger data; - utime_t rx_time; - uint32_t mem_size = 0; - // fragment with MF == 0 inidates it is the last fragment - bool last_frag_received = false; - - Packet get_assembled_packet(ethernet_address from, ethernet_address to); - int32_t merge(ip_hdr &h, uint16_t offset, Packet p); - bool is_complete(); - }; - std::unordered_map _frags; - std::list _frags_age; - static utime_t _frag_timeout; - static constexpr uint32_t _frag_low_thresh{3 * 1024 * 1024}; - static constexpr uint32_t _frag_high_thresh{4 * 1024 * 1024}; - uint32_t _frag_mem = 0; - circular_buffer _packetq; - unsigned _pkt_provider_idx = 0; - PerfCounters *perf_logger; - - private: - int handle_received_packet(Packet p, ethernet_address from); - bool forward(forward_hash& out_hash_data, Packet& p, size_t off); - Tub get_packet(); - bool in_my_netmask(ipv4_address a) const { - return !((a.ip ^ _host_address.ip) & _netmask.ip); - } - void frag_limit_mem(); - void frag_drop(ipv4_frag_id frag_id, uint32_t dropped_size) { - _frags.erase(frag_id); - _frag_mem -= dropped_size; - } - void frag_arm(utime_t now) { - auto tp = now + _frag_timeout; - frag_timefd.construct(center->create_time_event(tp.to_nsec() / 1000, frag_handler)); - } - void frag_arm() { - auto now = ceph_clock_now(); - frag_timefd.construct(center->create_time_event(now.to_nsec() / 1000, frag_handler)); - } - - public: - void frag_timeout(); - - public: - explicit ipv4(CephContext *c, EventCenter *cen, interface* netif); - ~ipv4() { - delete frag_handler; - } - void set_host_address(ipv4_address ip) { - _host_address = ip; - _arp.set_self_addr(ip); - } - ipv4_address host_address() { - return _host_address; - } - void set_gw_address(ipv4_address ip) { - _gw_address = ip; - } - ipv4_address gw_address() const { - return _gw_address; - } - void set_netmask_address(ipv4_address ip) { - _netmask = ip; - } - ipv4_address netmask_address() const { - return _netmask; - } - interface *netif() const { - return _netif; - } - // TODO or something. Should perhaps truly be a list - // of filters. With ordering. And blackjack. Etc. - // But for now, a simple single raw pointer suffices - void set_packet_filter(ip_packet_filter *f) { - _packet_filter = f; - } - ip_packet_filter * packet_filter() const { - return _packet_filter; - } - void send(ipv4_address to, ip_protocol_num proto_num, Packet p, ethernet_address e_dst); - tcp& get_tcp() { return *_tcp._tcp; } - void register_l4(proto_type id, ip_protocol* handler); - const hw_features& get_hw_features() const; - static bool needs_frag(Packet& p, ip_protocol_num proto_num, hw_features hw_features) { - if (p.len() + ipv4_hdr_len_min <= hw_features.mtu) - return false; - - if ((proto_num == ip_protocol_num::tcp && hw_features.tx_tso)) - return false; - - return true; - } - void learn(ethernet_address l2, ipv4_address l3) { - _arp.learn(l2, l3); - } - void register_packet_provider(ipv4_traits::packet_provider_type&& func) { - _pkt_providers.push_back(std::move(func)); - } - void wait_l2_dst_address(ipv4_address to, Packet p, resolution_cb cb); -}; - -template -inline void ipv4_l4::register_packet_provider( - ipv4_traits::packet_provider_type func) { - _inet.register_packet_provider([func] { - auto l4p = func(); - if (l4p) { - (*l4p).proto_num = ProtoNum; - } - return l4p; - }); -} - -template -inline void ipv4_l4::wait_l2_dst_address(ipv4_address to, Packet p, resolution_cb cb) { - _inet.wait_l2_dst_address(to, std::move(p), std::move(cb)); -} - -struct ip_hdr { - uint8_t ihl : 4; - uint8_t ver : 4; - uint8_t dscp : 6; - uint8_t ecn : 2; - uint16_t len; - uint16_t id; - uint16_t frag; - enum class frag_bits : uint8_t { mf = 13, df = 14, reserved = 15, offset_shift = 3 }; - uint8_t ttl; - uint8_t ip_proto; - uint16_t csum; - ipv4_address src_ip; - ipv4_address dst_ip; - uint8_t options[0]; - ip_hdr hton() { - ip_hdr hdr = *this; - hdr.len = ::hton(len); - hdr.id = ::hton(id); - hdr.frag = ::hton(frag); - hdr.csum = ::hton(csum); - hdr.src_ip.ip = ::hton(src_ip.ip); - hdr.dst_ip.ip = ::hton(dst_ip.ip); - return hdr; - } - ip_hdr ntoh() { - ip_hdr hdr = *this; - hdr.len = ::ntoh(len); - hdr.id = ::ntoh(id); - hdr.frag = ::ntoh(frag); - hdr.csum = ::ntoh(csum); - hdr.src_ip = src_ip.ntoh(); - hdr.dst_ip = dst_ip.ntoh(); - return hdr; - } - - bool mf() { return frag & (1 << uint8_t(frag_bits::mf)); } - bool df() { return frag & (1 << uint8_t(frag_bits::df)); } - uint16_t offset() { return frag << uint8_t(frag_bits::offset_shift); } -} __attribute__((packed)); - -template -struct l4connid::connid_hash : private std::hash, private std::hash { - size_t operator()(const l4connid& id) const noexcept { - using h1 = std::hash; - using h2 = std::hash; - return h1::operator()(id.local_ip) - ^ h1::operator()(id.foreign_ip) - ^ h2::operator()(id.local_port) - ^ h2::operator()(id.foreign_port); - } -}; - -#endif /* CEPH_MSG_IP_H */