]>
git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/demos/echo_demo.cc
2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
19 * Copyright (C) 2014 Cloudius Systems, Ltd.
23 #include <seastar/net/virtio.hh>
24 #include <seastar/net/dpdk.hh>
25 #include <seastar/core/reactor.hh>
26 #include <seastar/net/ip.hh>
31 using namespace seastar
;
34 void dump_packet(const packet
& p
) {
37 for (unsigned i
= 0; i
< std::min(f
.size
, size_t(30)); ++i
) {
39 std::sprintf(x
, " %02x", uint8_t(f
.base
[i
]));
45 future
<> echo_packet(net::qp
& netif
, packet p
) {
47 if (f
.size
< sizeof(eth_hdr
)) {
48 return make_ready_future
<>();
51 auto eh
= reinterpret_cast<eth_hdr
*>(f
.base
+ pos
);
54 if (eh
->eth_proto
!= 0x0800) {
55 return make_ready_future
<>();
57 auto iph
= reinterpret_cast<ip_hdr
*>(f
.base
+ pos
);
60 if (iph
->ver
!= 4 || iph
->ihl
< 5 || iph
->ip_proto
!= 1) {
61 return make_ready_future
<>();
63 auto ip_len
= iph
->len
;
64 auto icmph
= reinterpret_cast<icmp_hdr
*>(f
.base
+ pos
);
65 if (icmph
->type
!= icmp_hdr::msg_type::echo_request
) {
66 return make_ready_future
<>();
68 auto icmp_len
= ip_len
- iph
->ihl
* 4;
69 std::swap(eh
->src_mac
, eh
->dst_mac
);
70 std::swap(iph
->src_ip
, iph
->dst_ip
);
71 icmph
->type
= icmp_hdr::msg_type::echo_reply
;
75 icmph
->csum
= ip_checksum(icmph
, icmp_len
);
77 iph
->csum
= ip_checksum(iph
, iph
->ihl
* 4);
78 return netif
.send(std::move(p
));
81 #ifdef SEASTAR_HAVE_DPDK
84 std::cout
<<"Usage: echotest [-virtio|-dpdk]"<<std::endl
;
85 std::cout
<<" -virtio - use virtio backend (default)"<<std::endl
;
86 std::cout
<<" -dpdk - use dpdk-pmd backend"<<std::endl
;
90 int main(int ac
, char** av
) {
91 std::unique_ptr
<net::device
> dnet
;
94 boost::program_options::variables_map opts
;
95 opts
.insert(std::make_pair("tap-device", boost::program_options::variable_value(std::string("tap0"), false)));
97 #ifdef SEASTAR_HAVE_DPDK
103 if ((ac
== 1) || !std::strcmp(av
[1], "-virtio")) {
104 dnet
= create_virtio_net_device(opts
);
105 } else if (!std::strcmp(av
[1], "-dpdk")) {
106 dnet
= create_dpdk_net_device();
112 dnet
= create_virtio_net_device(opts
);
113 #endif // SEASTAR_HAVE_DPDK
115 auto qp
= dnet
->init_local_queue(opts
, 0);
117 dnet
->set_local_queue(std::move(qp
));
118 subscription
<packet
> rx
=
119 dnet
->receive([vnet
] (packet p
) {
120 return echo_packet(*vnet
, std::move(p
));