35class Virtio_net_request final :
public Net_request
41 explicit Virtio_net_transfer(Virtio_net_request
const &request)
49 _req_proc(_request.get_request_processor())
53 _cur_buf = request.first_buffer();
54 _req_id = _request.header();
58 Virtio_net_transfer(Virtio_net_transfer
const &) =
delete;
59 Virtio_net_transfer &operator = (Virtio_net_transfer
const &) =
delete;
61 void copy_header(Virtio_net::Hdr *dst_header)
const override
63 memcpy(dst_header, _request.header(),
sizeof(Virtio_net::Hdr));
68 return _cur_buf.
done() && !_req_proc.next(_request.dev()->
mem_info(), &_cur_buf);
72 Virtio_net_request
const &_request;
76 void dump_request(Port_iface *port)
const
78 Dbg debug(Dbg::Request, Dbg::Debug,
"REQ-VIO");
79 if (debug.is_active())
81 debug.printf(
"%s: Next packet: %p:%p - %x bytes\n",
82 port->get_name(), _header, _pkt.pos, _pkt.left);
83 if (_header->flags.raw || _header->gso_type)
85 debug.cprintf(
"flags:\t%x\n\t"
91 "\tnum buffer:\t%x\n",
93 _header->gso_type, _header->hdr_len,
95 _header->csum_start, _header->csum_offset,
96 _header->num_buffers);
103 Virtio_net_request(Virtio_net_request
const &) =
delete;
104 Virtio_net_request &operator = (Virtio_net_request
const &) =
delete;
107 Virtio_net_request(Virtio_net_request &&other)
109 _queue(other._queue),
110 _head(std::move(other._head)),
111 _req_proc(std::move(other._req_proc)),
112 _header(other._header)
114 _pkt = std::move(other._pkt);
117 other._queue =
nullptr;
120 Virtio_net_request &operator = (Virtio_net_request &&other)
126 _queue = other._queue;
127 _head = std::move(other._head);
128 _req_proc = std::move(other._req_proc);
129 _header = other._header;
130 _pkt = std::move(other._pkt);
133 other._queue =
nullptr;
139 L4virtio::Svr::Virtqueue::Request
const &req)
140 : _dev(dev), _queue(queue)
142 _head = _req_proc.start(_dev->mem_info(), req, &_pkt);
144 _header = (Virtio_net::Hdr *)_pkt.pos;
145 l4_uint32_t skipped = _pkt.skip(
sizeof(Virtio_net::Hdr));
147 if (
L4_UNLIKELY( (skipped !=
sizeof(Virtio_net::Hdr))
148 || (_pkt.done() && !_next_buffer(&_pkt))))
151 Dbg(Dbg::Queue, Dbg::Warn).printf(
"Invalid request\n");
156 ~Virtio_net_request()
160 {
return _header != 0; }
179 Dbg(Dbg::Request, Dbg::Debug)
180 .printf(
"Dropping incoming packets on monitor port\n");
187 auto head = req_proc.
start(dev->mem_info(), req, &pkt);
188 queue->
finish(head, dev, 0);
198 static std::optional<Virtio_net_request>
212 auto request = Virtio_net_request(dev, queue, r);
219 Buffer const &first_buffer()
const
222 Virtio_net::Hdr
const *header()
const
225 L4virtio::Svr::Request_processor
const &get_request_processor()
const
226 {
return _req_proc; }
228 Virtio_net
const *dev()
const
231 Virtio_net_transfer transfer_src()
const
232 {
return Virtio_net_transfer(*
this); }
237 return (_pkt.pos && _pkt.left >= Mac_addr::Addr_length)
245 return (_pkt.pos && _pkt.left >= Mac_addr::Addr_length * 2)
246 ?
Mac_addr(_pkt.pos + Mac_addr::Addr_length)
269 Virtio_net::Hdr *_header;
271 bool _next_buffer(
Buffer *buf)
282 if (_queue ==
nullptr || !_queue->ready())
285 Dbg(Dbg::Virtio, Dbg::Trace).printf(
"%s(%p)\n", __PRETTY_FUNCTION__,
this);
286 _queue->finish(_head, _dev, 0);