mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-21 06:33:31 +00:00
nic_router: send with individual composing functor
Normally, Interface::send always takes the base and size of the RAM region where a packet was composed and copies this finished packet at once into the packet stream RAM. But we want to be able to also compose packets directly in the packet stream RAM, so that no memcpy is needed. Thus, Interface::send now takes a functor that describes how to compose the packet, then allocates the packet stream RAM and applies the functor to this RAM. there is also a version of Interface::send that provides the old behavior but with the new back end. This way, we stay backwards-compatible. Issue #2626
This commit is contained in:
parent
4c76a87fec
commit
b6991f9c03
@ -927,21 +927,32 @@ void Interface::_handle_eth(void *const eth_base,
|
||||
}
|
||||
|
||||
|
||||
void Interface::send(Ethernet_frame ð, Genode::size_t const size)
|
||||
void Interface::send(Ethernet_frame ð, size_t eth_size)
|
||||
{
|
||||
send(eth_size, [&] (void *pkt_base) {
|
||||
Genode::memcpy(pkt_base, (void *)ð, eth_size);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void Interface::_send_alloc_pkt(Packet_descriptor &pkt,
|
||||
void * &pkt_base,
|
||||
size_t pkt_size)
|
||||
{
|
||||
pkt = _source().alloc_packet(pkt_size);
|
||||
pkt_base = _source().packet_content(pkt);
|
||||
}
|
||||
|
||||
|
||||
void Interface::_send_submit_pkt(Packet_descriptor &pkt,
|
||||
void * &pkt_base,
|
||||
size_t pkt_size)
|
||||
{
|
||||
_source().submit_packet(pkt);
|
||||
_domain.raise_tx_bytes(pkt_size);
|
||||
if (_config().verbose()) {
|
||||
log("(", _domain, " <- router) ", eth); }
|
||||
try {
|
||||
/* copy and submit packet */
|
||||
Packet_descriptor const pkt = _source().alloc_packet(size);
|
||||
char *content = _source().packet_content(pkt);
|
||||
Genode::memcpy((void *)content, (void *)ð, size);
|
||||
_source().submit_packet(pkt);
|
||||
_domain.raise_tx_bytes(size);
|
||||
}
|
||||
catch (Packet_stream_source::Packet_alloc_failed) {
|
||||
if (_config().verbose()) {
|
||||
log("Failed to allocate packet"); }
|
||||
log("(", _domain, " <- router) ",
|
||||
*reinterpret_cast<Ethernet_frame *>(pkt_base));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,6 +168,14 @@ class Net::Interface : public Genode::List<Interface>::Element
|
||||
|
||||
virtual Packet_stream_source &_source() = 0;
|
||||
|
||||
void _send_alloc_pkt(Genode::Packet_descriptor &pkt,
|
||||
void * &pkt_base,
|
||||
Genode::size_t pkt_size);
|
||||
|
||||
void _send_submit_pkt(Genode::Packet_descriptor &pkt,
|
||||
void * &pkt_base,
|
||||
Genode::size_t pkt_size);
|
||||
|
||||
|
||||
/***********************************
|
||||
** Packet-stream signal handlers **
|
||||
@ -212,10 +220,25 @@ class Net::Interface : public Genode::List<Interface>::Element
|
||||
|
||||
~Interface();
|
||||
|
||||
|
||||
void dhcp_allocation_expired(Dhcp_allocation &allocation);
|
||||
|
||||
void send(Ethernet_frame ð, Genode::size_t const eth_size);
|
||||
template <typename FUNC>
|
||||
void send(Genode::size_t pkt_size, FUNC && write_to_pkt)
|
||||
{
|
||||
try {
|
||||
Packet_descriptor pkt;
|
||||
void *pkt_base;
|
||||
|
||||
_send_alloc_pkt(pkt, pkt_base, pkt_size);
|
||||
write_to_pkt(pkt_base);
|
||||
_send_submit_pkt(pkt, pkt_base, pkt_size);
|
||||
}
|
||||
catch (Packet_stream_source::Packet_alloc_failed) {
|
||||
Genode::warning("failed to allocate packet");
|
||||
}
|
||||
}
|
||||
|
||||
void send(Ethernet_frame ð, Genode::size_t eth_size);
|
||||
|
||||
Link_list &dissolved_links(L3_protocol const protocol);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user