nic session: link-state change handling

A Nic::Session client can install a signal handler that is used to
propagate changes of the link-state by calling 'link_state_sigh()'.
The actual link state is queried via 'link_state()'.

The nic-driver interface now provides a Driver_notification callback,
which is used to forward link-state changes from the driver to the
Nic::Session_component.

The following drivers now provide real link state: dde_ipxe, nic_bridge,
and usb_drv. Currently, OpenVPN, Linux nic_drv, and lan9118 do not
support link state and always report link up.

Fixes #1327
This commit is contained in:
Josef Söntgen 2015-03-11 11:33:03 +01:00 committed by Christian Helmuth
parent e4f6fca355
commit dd47129bef
21 changed files with 314 additions and 67 deletions

View File

@ -15,6 +15,11 @@
#ifndef _DDE_IPXE__NIC_H_
#define _DDE_IPXE__NIC_H_
/**
* Link-state change callback
*/
typedef void (*dde_ipxe_nic_link_cb)(void);
/**
* Packet reception callback
*
@ -27,14 +32,14 @@ typedef void (*dde_ipxe_nic_rx_cb)(unsigned if_index, const char *packet, unsign
/**
* Register packet reception callback
*
* \param cb new callback function
*
* \return old callback function pointer
* \param rx_cb packet-reception callback function
* \param link_cb link-state change callback function
*
* This registers a function pointer as rx callback. Incoming ethernet packets
* are passed to this function.
*/
extern dde_ipxe_nic_rx_cb dde_ipxe_nic_register_rx_callback(dde_ipxe_nic_rx_cb cb);
extern void dde_ipxe_nic_register_callbacks(dde_ipxe_nic_rx_cb rx_cb,
dde_ipxe_nic_link_cb link_cb);
/**
* Send packet
@ -57,6 +62,15 @@ extern int dde_ipxe_nic_tx(unsigned if_index, const char *packet, unsigned packe
*/
extern int dde_ipxe_nic_get_mac_addr(unsigned if_index, char *out_mac_addr);
/**
* Get current link-state of device
*
* \param if_index index of the receiving network interface
*
* \return 1 if link is up, 0 if no link is detected
*/
extern int dde_ipxe_nic_link_state(unsigned if_index);
/**
* Initialize network sub-system
*

View File

@ -32,29 +32,32 @@ namespace Ipxe {
static Driver *instance;
static void dde_rx_handler(unsigned if_index,
const char *packet,
unsigned packet_len)
private:
Nic::Mac_address _mac_addr;
Nic::Rx_buffer_alloc &_alloc;
Nic::Driver_notification &_notify;
static void _rx_callback(unsigned if_index,
const char *packet,
unsigned packet_len)
{
instance->rx_handler(packet, packet_len);
}
private:
Nic::Mac_address _mac_addr;
Nic::Rx_buffer_alloc &_alloc;
static void _link_callback() { instance->link_state_changed(); }
public:
Driver(Nic::Rx_buffer_alloc &alloc)
: _alloc(alloc)
Driver(Nic::Rx_buffer_alloc &alloc, Nic::Driver_notification &notify)
: _alloc(alloc), _notify(notify)
{
PINF("--- init iPXE NIC");
int cnt = dde_ipxe_nic_init();
PINF(" number of devices: %d", cnt);
PINF("--- init rx_callbacks");
dde_ipxe_nic_register_rx_callback(dde_rx_handler);
PINF("--- init callbacks");
dde_ipxe_nic_register_callbacks(_rx_callback, _link_callback);
dde_ipxe_nic_get_mac_addr(1, _mac_addr.addr);
PINF("--- get MAC address %02x:%02x:%02x:%02x:%02x:%02x",
@ -70,16 +73,23 @@ namespace Ipxe {
Genode::memcpy(buffer, packet, packet_len);
_alloc.submit();
} catch (...) {
PDBG("failed to process received packet");
PDBG("failed to process received packet");
}
}
void link_state_changed() { _notify.link_state_changed(); }
/***************************
** Nic::Driver interface **
***************************/
Nic::Mac_address mac_address() { return _mac_addr; }
Nic::Mac_address mac_address() override { return _mac_addr; }
bool link_state() override
{
return dde_ipxe_nic_link_state(1);
}
void tx(char const *packet, Genode::size_t size)
{
@ -87,7 +97,6 @@ namespace Ipxe {
PWRN("Sending packet failed!");
}
/******************************
** Irq_activation interface **
******************************/
@ -97,9 +106,10 @@ namespace Ipxe {
class Driver_factory : public Nic::Driver_factory
{
Nic::Driver *create(Nic::Rx_buffer_alloc &alloc)
Nic::Driver *create(Nic::Rx_buffer_alloc &alloc,
Nic::Driver_notification &notify)
{
Driver::instance = new (Genode::env()->heap()) Ipxe::Driver(alloc);
Driver::instance = new (Genode::env()->heap()) Ipxe::Driver(alloc, notify);
return Driver::instance;
}

View File

@ -36,32 +36,35 @@ namespace Ipxe {
static Driver *instance;
static void dde_rx_handler(unsigned if_index,
const char *packet,
unsigned packet_len)
private:
Nic::Mac_address _mac_addr;
Nic::Rx_buffer_alloc &_alloc;
Nic::Driver_notification &_notify;
Timer::Connection _timer;
Nic::Measurement _stat;
static void _rx_callback(unsigned if_index,
const char *packet,
unsigned packet_len)
{
instance->rx_handler_stat(packet, packet_len);
}
private:
Nic::Mac_address _mac_addr;
Nic::Rx_buffer_alloc &_alloc;
Timer::Connection _timer;
Nic::Measurement _stat;
static void _link_callback() { instance->link_state_changed(); }
public:
Driver(Nic::Rx_buffer_alloc &alloc)
: _alloc(alloc), _stat(_timer)
Driver(Nic::Rx_buffer_alloc &alloc, Nic::Driver_notification &notify)
: _alloc(alloc), _notify(notify), _stat(_timer)
{
PINF("--- init iPXE NIC");
int cnt = dde_ipxe_nic_init();
PINF(" number of devices: %d", cnt);
PINF("--- init rx_callbacks");
dde_ipxe_nic_register_rx_callback(dde_rx_handler);
PINF("--- init callbacks");
dde_ipxe_nic_register_callbacks(_rx_callback, _link_callback);
dde_ipxe_nic_get_mac_addr(1, _mac_addr.addr);
PINF("--- get MAC address %02x:%02x:%02x:%02x:%02x:%02x",
@ -90,6 +93,8 @@ namespace Ipxe {
_alloc.submit();
}
void link_state_changed() { _notify.link_state_changed(); }
/***************************
** Nic::Driver interface **
@ -97,6 +102,11 @@ namespace Ipxe {
Nic::Mac_address mac_address() { return _mac_addr; }
bool link_state() override
{
return dde_ipxe_nic_link_state(1);
}
void tx(char const *packet, Genode::size_t size)
{
if (dde_ipxe_nic_tx(1, packet, size))
@ -112,9 +122,9 @@ namespace Ipxe {
class Driver_factory : public Nic::Driver_factory
{
Nic::Driver *create(Nic::Rx_buffer_alloc &alloc)
Nic::Driver *create(Nic::Rx_buffer_alloc &alloc, Nic::Driver_notification &notify)
{
Driver::instance = new (Genode::env()->heap()) Ipxe::Driver(alloc);
Driver::instance = new (Genode::env()->heap()) Ipxe::Driver(alloc, notify);
return Driver::instance;
}

View File

@ -48,9 +48,15 @@ static struct dde_kit_sem *bh_sema;
static struct net_device *net_dev;
/**
* RX callback function pointer
* Link-state change detected
*/
static dde_ipxe_nic_rx_cb rx_callback;
static int link_state_changed;
/**
* Callback function pointers
*/
static dde_ipxe_nic_link_cb link_callback;
static dde_ipxe_nic_rx_cb rx_callback;
/**
* Known iPXE driver structures (located in the driver binaries)
@ -71,7 +77,6 @@ static struct pci_driver *pci_drivers[] = {
&pcnet32_driver
};
/**
* Update BARs of PCI device
*/
@ -201,9 +206,15 @@ static void irq_handler(void *p)
{
ENTER;
/* check for the link-state to change on each interrupt */
int link_ok = netdev_link_ok(net_dev);
/* poll the device for packets and also link-state changes */
netdev_poll(net_dev);
dde_kit_sem_up(bh_sema);
link_state_changed = (link_ok != netdev_link_ok(net_dev));
LEAVE;
}
@ -220,6 +231,15 @@ static void bh_handler(void *p)
ENTER;
/* report link-state changes */
if (link_state_changed) {
LEAVE;
if (link_callback)
link_callback();
ENTER;
link_state_changed = 0;
}
struct io_buffer *iobuf;
while ((iobuf = netdev_rx_dequeue(net_dev))) {
LEAVE;
@ -238,15 +258,30 @@ static void bh_handler(void *p)
** API implementation **
************************/
dde_ipxe_nic_rx_cb dde_ipxe_nic_register_rx_callback(dde_ipxe_nic_rx_cb cb)
void dde_ipxe_nic_register_callbacks(dde_ipxe_nic_rx_cb rx_cb,
dde_ipxe_nic_link_cb link_cb)
{
ENTER;
dde_ipxe_nic_rx_cb old = rx_callback;
rx_callback = cb;
rx_callback = rx_cb;
link_callback = link_cb;
LEAVE;
return old;
}
int dde_ipxe_nic_link_state(unsigned if_index)
{
if (if_index != 1)
return -1;
ENTER;
int link_state = netdev_link_ok(net_dev);
LEAVE;
return link_state;
}

View File

@ -80,6 +80,11 @@ namespace Nic {
*/
virtual Mac_address mac_address() = 0;
/**
* Return current link-state (true if link detected)
*/
virtual bool link_state() = 0;
/**
* Set session belonging to this driver
*/
@ -130,6 +135,8 @@ namespace Nic {
bool _tx_alloc; /* get next packet from client or use _tx_packet */
Packet_descriptor _tx_packet; /* saved packet in case of driver errors */
Signal_context_capability _link_state_sigh;
void _send_packet_avail_signal() {
Signal_transmitter(_tx.sigh_packet_avail()).submit(); }
@ -256,8 +263,23 @@ namespace Nic {
_tx_alloc(true)
{ _device->session(this); }
/**
* Link state changed (called from driver)
*/
void link_state_changed()
{
if (_link_state_sigh.valid())
Genode::Signal_transmitter(_link_state_sigh).submit();
}
Mac_address mac_address() { return _device->mac_address(); }
bool link_state() override {
return _device->link_state(); }
void link_state_sigh(Genode::Signal_context_capability sigh) {
_link_state_sigh = sigh; }
/**
* Send packet to client (called form driver)
*/

View File

@ -144,6 +144,7 @@ class Nic_device : public Nic::Device
struct net_device *_ndev; /* Linux-net device */
fixup_t _tx_fixup;
bool const _burst;
bool _has_link { false };
public:
@ -177,11 +178,29 @@ class Nic_device : public Nic::Device
static Nic_device *add(struct net_device *ndev) {
return new (Genode::env()->heap()) Nic_device(ndev); }
/**
* Report link state
*/
void link_state(bool link)
{
/* only report changes of the link state */
if (link == _has_link)
return;
_has_link = link;
if (_session)
_session->link_state_changed();
}
/**********************
** Device interface **
**********************/
bool link_state() override { return _has_link; }
/**
* Submit packet to driver
*/
@ -344,12 +363,16 @@ int netif_carrier_ok(const struct net_device *dev)
void netif_carrier_on(struct net_device *dev)
{
dev->state &= ~(1 << __LINK_STATE_NOCARRIER);
if (_nic)
_nic->link_state(true);
}
void netif_carrier_off(struct net_device *dev)
{
dev->state |= 1 << __LINK_STATE_NOCARRIER;
if (_nic)
_nic->link_state(false);
}
#ifdef GENODE_NET_STAT

View File

@ -39,13 +39,16 @@ namespace Nic {
class Nic::Session_component : public Genode::Allocator_avl,
public Session_rpc_object, public Rx_buffer_alloc
public Session_rpc_object, public Rx_buffer_alloc,
public Driver_notification
{
private:
Driver_factory &_driver_factory;
Driver &_driver;
Genode::Signal_context_capability _link_state_sigh;
/* rx packet descriptor */
Genode::Packet_descriptor _curr_rx_packet;
@ -126,7 +129,7 @@ class Nic::Session_component : public Genode::Allocator_avl,
Genode::env()->ram_session()->alloc(rx_buf_size),
static_cast<Genode::Range_allocator *>(this), ep),
_driver_factory(driver_factory),
_driver(*driver_factory.create(*this)),
_driver(*driver_factory.create(*this, *this)),
_tx_thread(_tx.sink(), _driver)
{ }
@ -138,12 +141,21 @@ class Nic::Session_component : public Genode::Allocator_avl,
_driver_factory.destroy(&_driver);
}
/***********************************
** Driver-notification interface **
***********************************/
void link_state_changed() override
{
if (_link_state_sigh.valid())
Genode::Signal_transmitter(_link_state_sigh).submit();
}
/*******************************
** Rx_buffer_alloc interface **
*******************************/
void *alloc(Genode::size_t size)
void *alloc(Genode::size_t size) override
{
/* assign rx packet descriptor */
_curr_rx_packet = _rx.source()->alloc_packet(size);
@ -151,7 +163,7 @@ class Nic::Session_component : public Genode::Allocator_avl,
return _rx.source()->packet_content(_curr_rx_packet);
}
void submit()
void submit() override
{
/* check for acknowledgements from the client */
while (_rx.source()->ack_avail()) {
@ -175,8 +187,14 @@ class Nic::Session_component : public Genode::Allocator_avl,
****************************/
Mac_address mac_address() { return _driver.mac_address(); }
bool link_state() { return _driver.link_state(); }
Tx::Sink* tx_sink() { return _tx.sink(); }
Rx::Source* rx_source() { return _rx.source(); }
void link_state_sigh(Genode::Signal_context_capability sigh) override
{
_link_state_sigh = sigh;
}
};

View File

@ -22,6 +22,7 @@ namespace Nic {
struct Rx_buffer_alloc;
struct Driver;
struct Driver_factory;
struct Driver_notification;
}
@ -42,6 +43,12 @@ struct Nic::Rx_buffer_alloc
};
/**
* Interface for driver-to-component notifications
*/
struct Nic::Driver_notification { virtual void link_state_changed() = 0; };
/**
* Interface to be implemented by the device-specific driver code
*/
@ -52,6 +59,11 @@ struct Nic::Driver : Genode::Irq_handler
*/
virtual Mac_address mac_address() = 0;
/**
* Return link state (true if link detected)
*/
virtual bool link_state() = 0;
/**
* Transmit packet
*
@ -83,8 +95,10 @@ struct Nic::Driver_factory
*
* \param rx_buffer_alloc buffer allocator used for storing incoming
* packets
* \param notifier callback for notifications
*/
virtual Driver *create(Rx_buffer_alloc &rx_buffer_alloc) = 0;
virtual Driver *create(Rx_buffer_alloc &rx_buffer_alloc,
Driver_notification &notify) = 0;
/**
* Destroy driver

View File

@ -56,6 +56,13 @@ class Nic::Session_client : public Genode::Rpc_client<Session>
Rx *rx_channel() { return &_rx; }
Tx::Source *tx() { return _tx.source(); }
Rx::Sink *rx() { return _rx.sink(); }
void link_state_sigh(Genode::Signal_context_capability sigh) override
{
call<Rpc_link_state_sigh>(sigh);
}
bool link_state() override { return call<Rpc_link_state>(); }
};
#endif /* _INCLUDE__NIC_SESSION__CLIENT_H_ */

View File

@ -93,6 +93,15 @@ struct Nic::Session : Genode::Session
*/
virtual Rx::Sink *rx() { return 0; }
/**
* Request current link state of network adapter (true means link detected)
*/
virtual bool link_state() = 0;
/**
* Register signal handler for link state changes
*/
virtual void link_state_sigh(Genode::Signal_context_capability sigh) = 0;
/*******************
** RPC interface **
@ -101,8 +110,12 @@ struct Nic::Session : Genode::Session
GENODE_RPC(Rpc_mac_address, Mac_address, mac_address);
GENODE_RPC(Rpc_tx_cap, Genode::Capability<Tx>, _tx_cap);
GENODE_RPC(Rpc_rx_cap, Genode::Capability<Rx>, _rx_cap);
GENODE_RPC(Rpc_link_state, bool, link_state);
GENODE_RPC(Rpc_link_state_sigh, void, link_state_sigh,
Genode::Signal_context_capability);
GENODE_RPC_INTERFACE(Rpc_mac_address, Rpc_tx_cap, Rpc_rx_cap);
GENODE_RPC_INTERFACE(Rpc_mac_address, Rpc_link_state,
Rpc_link_state_sigh, Rpc_tx_cap, Rpc_rx_cap);
};
#endif /* _INCLUDE__NIC_SESSION__NIC_SESSION_H_ */

View File

@ -72,6 +72,7 @@ class Lan9118 : public Nic::Driver
Timer::Connection _timer;
Nic::Rx_buffer_alloc &_rx_buffer_alloc;
Nic::Mac_address _mac_addr;
Nic::Driver_notification &_notify;
enum { IRQ_STACK_SIZE = 4096 };
Genode::Irq_activation _irq_activation;
@ -201,11 +202,13 @@ class Lan9118 : public Nic::Driver
* \throw Device_not_supported
*/
Lan9118(Genode::addr_t mmio_base, Genode::size_t mmio_size, int irq,
Nic::Rx_buffer_alloc &rx_buffer_alloc)
Nic::Rx_buffer_alloc &rx_buffer_alloc,
Nic::Driver_notification &notify)
:
_mmio(mmio_base, mmio_size),
_reg_base(_mmio.local_addr<Genode::uint32_t>()),
_rx_buffer_alloc(rx_buffer_alloc),
_notify(notify),
_irq_activation(irq, *this, IRQ_STACK_SIZE)
{
unsigned long const id_rev = _reg_read(ID_REV),
@ -287,6 +290,8 @@ class Lan9118 : public Nic::Driver
_mac_csr_write(MAC_CR, 0);
}
void link_state_changed() { _notify.link_state_changed(); }
/***************************
** Nic::Driver interface **
@ -297,6 +302,12 @@ class Lan9118 : public Nic::Driver
return _mac_addr;
}
bool link_state()
{
/* XXX always return true for now */
return true;
}
void tx(char const *packet, Genode::size_t size)
{
/* limit size to 11 bits, the maximum supported by lan9118 */

View File

@ -37,10 +37,11 @@ int main(int, char **)
*/
struct Lan9118_driver_factory : Nic::Driver_factory
{
Nic::Driver *create(Nic::Rx_buffer_alloc &alloc)
Nic::Driver *create(Nic::Rx_buffer_alloc &alloc,
Nic::Driver_notification &notify)
{
return new (env()->heap())
Lan9118(LAN9118_PHYS, LAN9118_SIZE, LAN9118_IRQ, alloc);
Lan9118(LAN9118_PHYS, LAN9118_SIZE, LAN9118_IRQ, alloc, notify);
}
void destroy(Nic::Driver *driver)

View File

@ -67,8 +67,9 @@ class Linux_driver : public Nic::Driver
}
};
Nic::Mac_address _mac_addr;
Nic::Rx_buffer_alloc &_alloc;
Nic::Mac_address _mac_addr;
Nic::Rx_buffer_alloc &_alloc;
Nic::Driver_notification &_notify;
char _packet_buffer[1514]; /* maximum ethernet packet length */
int _tap_fd;
@ -114,8 +115,11 @@ class Linux_driver : public Nic::Driver
public:
Linux_driver(Nic::Rx_buffer_alloc &alloc)
: _alloc(alloc), _tap_fd(_setup_tap_fd()), _rx_thread(_tap_fd, *this)
Linux_driver(Nic::Rx_buffer_alloc &alloc,
Nic::Driver_notification &notify)
:
_alloc(alloc), _notify(notify),
_tap_fd(_setup_tap_fd()), _rx_thread(_tap_fd, *this)
{
/* try using configured MAC address */
try {
@ -141,6 +145,8 @@ class Linux_driver : public Nic::Driver
_rx_thread.start();
}
void link_state_changed() { _notify.link_state_changed(); }
/***************************
** Nic::Driver interface **
@ -148,6 +154,12 @@ class Linux_driver : public Nic::Driver
Nic::Mac_address mac_address() { return _mac_addr; }
bool link_state()
{
/* XXX return always true for now */
return true;
}
void tx(char const *packet, Genode::size_t size)
{
int ret;
@ -200,9 +212,10 @@ int main(int, char **)
*/
struct Linux_driver_factory : Nic::Driver_factory
{
Nic::Driver *create(Nic::Rx_buffer_alloc &alloc)
Nic::Driver *create(Nic::Rx_buffer_alloc &alloc,
Nic::Driver_notification &notify)
{
return new (env()->heap()) Linux_driver(alloc);
return new (env()->heap()) Linux_driver(alloc, notify);
}
void destroy(Nic::Driver *driver)

View File

@ -102,6 +102,10 @@ void Session_component::_free_ipv4_node()
}
bool Session_component::link_state() {
return Net::Env::nic()->link_state(); }
void Session_component::set_ipv4_address(Ipv4_packet::Ipv4_address ip_addr)
{
_free_ipv4_node();

View File

@ -105,6 +105,8 @@ namespace Net {
Mac_address_node _mac_node;
Ipv4_address_node *_ipv4_node;
Genode::Signal_context_capability _link_state_sigh;
void _free_ipv4_node();
public:
@ -137,8 +139,23 @@ namespace Net {
return m;
}
void link_state_changed()
{
if (_link_state_sigh.valid())
Genode::Signal_transmitter(_link_state_sigh).submit();
}
void set_ipv4_address(Ipv4_packet::Ipv4_address ip_addr);
/****************************************
** Nic::Driver notification interface **
****************************************/
bool link_state();
void link_state_sigh(Genode::Signal_context_capability sigh) {
_link_state_sigh = sigh; }
/******************************
** Packet_handler interface **
******************************/

View File

@ -134,4 +134,5 @@ Net::Nic::Nic()
_nic.rx_channel()->sigh_packet_avail(_sink_submit);
_nic.tx_channel()->sigh_ack_avail(_source_ack);
_nic.tx_channel()->sigh_ready_to_submit(_source_submit);
_nic.link_state_sigh(_client_link_state);
}

View File

@ -45,6 +45,7 @@ class Net::Nic : public Net::Packet_handler
::Nic::Connection *nic() { return &_nic; }
Ethernet_frame::Mac_address mac() { return _mac; }
bool link_state() { return _nic.link_state(); }
/******************************
** Packet_handler interface **

View File

@ -54,6 +54,16 @@ void Packet_handler::_ready_to_ack(unsigned)
}
void Packet_handler::_link_state(unsigned)
{
Mac_address_node *node = Env::vlan()->mac_list()->first();
while (node) {
node->component()->link_state_changed();
node = node->next();
}
}
void Packet_handler::broadcast_to_clients(Ethernet_frame *eth, Genode::size_t size)
{
/* check whether it's really a broadcast packet */
@ -121,5 +131,6 @@ Packet_handler::Packet_handler()
: _sink_ack(*Net::Env::receiver(), *this, &Packet_handler::_ack_avail),
_sink_submit(*Net::Env::receiver(), *this, &Packet_handler::_ready_to_submit),
_source_ack(*Net::Env::receiver(), *this, &Packet_handler::_ready_to_ack),
_source_submit(*Net::Env::receiver(), *this, &Packet_handler::_packet_avail)
_source_submit(*Net::Env::receiver(), *this, &Packet_handler::_packet_avail),
_client_link_state(*Net::Env::receiver(), *this, &Packet_handler::_link_state)
{ }

View File

@ -65,12 +65,18 @@ class Net::Packet_handler
*/
void _packet_avail(unsigned) { }
/**
* the link-state of changed
*/
void _link_state(unsigned);
protected:
Genode::Signal_dispatcher<Packet_handler> _sink_ack;
Genode::Signal_dispatcher<Packet_handler> _sink_submit;
Genode::Signal_dispatcher<Packet_handler> _source_ack;
Genode::Signal_dispatcher<Packet_handler> _source_submit;
Genode::Signal_dispatcher<Packet_handler> _client_link_state;
public:

View File

@ -142,6 +142,14 @@ namespace Nic {
Mac_address result = {{1,2,3,4,5,6}};
return result;
}
bool link_state()
{
/* XXX always return true, for now */
return true;
}
void link_state_sigh(Genode::Signal_context_capability sigh) { }
};
class Root : public Genode::Root_component<Session_component>

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
* Copyright (C) 2014-2015 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
@ -87,8 +87,9 @@ class Nic_driver : public Tuntap_device,
{
private:
Nic::Mac_address _mac_addr {{ 0x02, 0x00, 0x00, 0x00, 0x00, 0x01 }};
Nic::Rx_buffer_alloc &_alloc;
Nic::Mac_address _mac_addr {{ 0x02, 0x00, 0x00, 0x00, 0x00, 0x01 }};
Nic::Rx_buffer_alloc &_alloc;
Nic::Driver_notification &_notify;
char const *_packet;
@ -101,10 +102,9 @@ class Nic_driver : public Tuntap_device,
public:
Nic_driver(Nic::Rx_buffer_alloc &alloc)
Nic_driver(Nic::Rx_buffer_alloc &alloc, Nic::Driver_notification &notify)
:
_alloc(alloc),
_packet(0)
_alloc(alloc), _notify(notify), _packet(0)
{
if (pipe(_pipefd)) {
PERR("could not create pipe");
@ -114,6 +114,7 @@ class Nic_driver : public Tuntap_device,
~Nic_driver() { PDBG("should probably be implemented"); }
void link_state_changed() { _notify.link_state_changed(); }
/***************************
** Nic::Driver interface **
@ -121,6 +122,12 @@ class Nic_driver : public Tuntap_device,
Nic::Mac_address mac_address() { return _mac_addr; }
bool link_state()
{
/* XXX always return true for now */
return true;
}
void tx(char const *packet, Genode::size_t size)
{
PDBGV("packet:0x%p size:%zu", packet, size);
@ -185,11 +192,12 @@ struct Main
Nic_driver *drv { 0 };
Openvpn_thread *openvpn { 0 };
Nic::Driver *create(Nic::Rx_buffer_alloc &alloc)
Nic::Driver *create(Nic::Rx_buffer_alloc &alloc,
Nic::Driver_notification &notify)
{
/* there can be only one */
if (!drv) {
drv = new (Genode::env()->heap()) Nic_driver(alloc);
drv = new (Genode::env()->heap()) Nic_driver(alloc, notify);
/**
* Setting the pointer in this manner is quite hackish but it has