mirror of
https://github.com/genodelabs/genode.git
synced 2025-03-23 12:35:41 +00:00
vbox: improve network backend
VirtualBox mainly derives the initial link-state for its device models from checking the <Adapter ... cable="true"/> attribute. Our backend only propagates the current state of the Nic session if it receives a link-state signal. This may lead to problems if a guest detects a link up state when it is actually down and wants to use the interface. The backend now queries the Nic session and sets the link-state accordingly when it is constructed. In case there is no link do not attempt to submit a packet to the packet stream but return with an error so that upper layers can handle it. Enable signals for network on poweron and not already during construction. The network model may be not yet ready to process incoming signals and data. Fixes #2117.
This commit is contained in:
parent
f75f199947
commit
9ba7b2edde
@ -89,6 +89,8 @@ class Nic_client
|
||||
Genode::Signal_dispatcher<Nic_client> _rx_ready_to_ack_dispatcher;
|
||||
Genode::Signal_dispatcher<Nic_client> _destruct_dispatcher;
|
||||
|
||||
bool _link_up = false;
|
||||
|
||||
/* VM <-> device driver (down) <-> nic_client (up) <-> nic session */
|
||||
PPDMINETWORKDOWN _down_rx;
|
||||
PPDMINETWORKCONFIG _down_rx_config;
|
||||
@ -115,9 +117,11 @@ class Nic_client
|
||||
|
||||
void _handle_link_state(unsigned)
|
||||
{
|
||||
_link_up = _nic.link_state();
|
||||
|
||||
_down_rx_config->pfnSetLinkState(_down_rx_config,
|
||||
_nic.link_state() ? PDMNETWORKLINKSTATE_UP
|
||||
: PDMNETWORKLINKSTATE_DOWN);
|
||||
_link_up ? PDMNETWORKLINKSTATE_UP
|
||||
: PDMNETWORKLINKSTATE_DOWN);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -167,11 +171,7 @@ class Nic_client
|
||||
_destruct_dispatcher(_sig_rec, *this, &Nic_client::_handle_destruct),
|
||||
_down_rx(drvtap->pIAboveNet),
|
||||
_down_rx_config(drvtap->pIAboveConfig)
|
||||
{
|
||||
_nic.link_state_sigh(_link_state_dispatcher);
|
||||
_nic.rx_channel()->sigh_packet_avail(_rx_packet_avail_dispatcher);
|
||||
_nic.rx_channel()->sigh_ready_to_ack(_rx_ready_to_ack_dispatcher);
|
||||
}
|
||||
{ }
|
||||
|
||||
~Nic_client()
|
||||
{
|
||||
@ -179,12 +179,24 @@ class Nic_client
|
||||
destroy(env()->heap(), _tx_block_alloc);
|
||||
}
|
||||
|
||||
void enable_signals()
|
||||
{
|
||||
_nic.link_state_sigh(_link_state_dispatcher);
|
||||
_nic.rx_channel()->sigh_packet_avail(_rx_packet_avail_dispatcher);
|
||||
_nic.rx_channel()->sigh_ready_to_ack(_rx_ready_to_ack_dispatcher);
|
||||
|
||||
/* set initial link-state */
|
||||
_handle_link_state(1);
|
||||
}
|
||||
|
||||
Genode::Signal_context_capability &dispatcher() { return _destruct_dispatcher; }
|
||||
Genode::Signal_receiver &sig_rec() { return _sig_rec; }
|
||||
Nic::Mac_address mac_address() { return _nic.mac_address(); }
|
||||
|
||||
int send_packet(void *packet, uint32_t packet_len)
|
||||
{
|
||||
if (!_link_up) { return VERR_NET_DOWN; }
|
||||
|
||||
Nic::Packet_descriptor tx_packet = _alloc_tx_packet(packet_len);
|
||||
|
||||
char *tx_content = _nic.tx()->packet_content(tx_packet);
|
||||
@ -548,6 +560,14 @@ static DECLCALLBACK(int) drvNicConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uin
|
||||
}
|
||||
|
||||
|
||||
static DECLCALLBACK(void) drvNicPowerOn(PPDMDRVINS pDrvIns)
|
||||
{
|
||||
PDRVNIC pThis = PDMINS_2_DATA(pDrvIns, PDRVNIC);
|
||||
|
||||
if (pThis && pThis->nic_client)
|
||||
pThis->nic_client->enable_signals();
|
||||
}
|
||||
|
||||
/**
|
||||
* Nic network transport driver registration record.
|
||||
*/
|
||||
@ -579,8 +599,7 @@ const PDMDRVREG g_DrvHostInterface =
|
||||
NULL,
|
||||
/* pfnIOCtl */
|
||||
NULL,
|
||||
/* pfnPowerOn */
|
||||
NULL,
|
||||
drvNicPowerOn,
|
||||
/* pfnReset */
|
||||
NULL,
|
||||
/* pfnSuspend */
|
||||
|
Loading…
x
Reference in New Issue
Block a user