mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-16 07:27:35 +00:00
lxip: support link_state handling
* (re-)configure address when link state goes up * propagate link state to Linux code issue #5471
This commit is contained in:
parent
6a0c9f50ea
commit
f0a75b75fb
@ -365,6 +365,12 @@ int netdev_register_kobject(struct net_device * ndev)
|
||||
}
|
||||
|
||||
|
||||
void netdev_unregister_kobject(struct net_device * ndev)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sched/signal.h>
|
||||
|
||||
int send_sig(int sig,struct task_struct * p,int priv)
|
||||
|
@ -42,12 +42,16 @@ struct Main
|
||||
: env(env), io_progress(io_progress)
|
||||
{ }
|
||||
|
||||
void _io_progress()
|
||||
{
|
||||
if (io_progress && io_progress->callback)
|
||||
io_progress->callback(io_progress->data);
|
||||
}
|
||||
|
||||
void handle_schedule()
|
||||
{
|
||||
Lx_kit::env().scheduler.execute();
|
||||
|
||||
if (io_progress && io_progress->callback)
|
||||
io_progress->callback(io_progress->data);
|
||||
_io_progress();
|
||||
}
|
||||
|
||||
void handle_nic_client()
|
||||
@ -62,13 +66,13 @@ struct Main
|
||||
lx_emul_task_unblock(lx_nic_client_rx_task());
|
||||
Lx_kit::env().scheduler.execute();
|
||||
|
||||
if (io_progress && io_progress->callback)
|
||||
io_progress->callback(io_progress->data);
|
||||
_io_progress();
|
||||
}
|
||||
|
||||
void handle_link_state()
|
||||
{
|
||||
Genode::error("handle_link_state: not implemented");
|
||||
socket_update_link_state();
|
||||
_io_progress();
|
||||
}
|
||||
|
||||
void init()
|
||||
|
@ -25,12 +25,38 @@ static struct genode_nic_client *dev_nic_client(struct net_device *dev)
|
||||
}
|
||||
|
||||
|
||||
static struct net_device *dev_net_device(void)
|
||||
{
|
||||
return dev_get_by_name(&init_net, "eth0");
|
||||
}
|
||||
|
||||
|
||||
static int net_open(struct net_device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool lx_nic_client_link_state(void)
|
||||
{
|
||||
return netif_carrier_ok(dev_net_device());
|
||||
}
|
||||
|
||||
|
||||
bool lx_nic_client_update_link_state(void)
|
||||
{
|
||||
struct net_device *dev = dev_net_device();
|
||||
bool state = genode_nic_client_link_state(dev_nic_client(dev));
|
||||
|
||||
if (state == false && netif_carrier_ok(dev))
|
||||
netif_carrier_off(dev);
|
||||
if (state == true && !netif_carrier_ok(dev))
|
||||
netif_carrier_on(dev);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
struct genode_nic_client_tx_packet_context
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
@ -82,7 +108,7 @@ static int driver_net_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
stats->tx_packets++;
|
||||
stats->tx_bytes += skb->len;
|
||||
|
||||
lx_nic_client_schedule_peer();
|
||||
socket_schedule_peer();
|
||||
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
@ -155,7 +181,7 @@ static int rx_task_function(void *arg)
|
||||
&ctx)) {
|
||||
progress = true; }
|
||||
|
||||
if (progress) lx_nic_client_schedule_peer();
|
||||
if (progress) socket_schedule_peer();
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -192,6 +218,14 @@ static int __init virtio_net_driver_init(void)
|
||||
goto out_nic;
|
||||
}
|
||||
|
||||
if (dev_net_device() != dev) {
|
||||
printk("error: net device name is \"%s\", but must be \"eth0\"\n",
|
||||
dev->name);
|
||||
BUG();
|
||||
}
|
||||
|
||||
lx_nic_client_update_link_state();
|
||||
|
||||
/* create RX task */
|
||||
pid = kernel_thread(rx_task_function, dev, "rx_task", CLONE_FS | CLONE_FILES);
|
||||
|
||||
|
@ -18,9 +18,17 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* net_driver.c */
|
||||
struct task_struct;
|
||||
struct task_struct *lx_nic_client_rx_task(void);
|
||||
void lx_nic_client_schedule_peer(void);
|
||||
bool lx_nic_client_link_state(void);
|
||||
bool lx_nic_client_update_link_state(void);
|
||||
|
||||
/* socket.cc */
|
||||
void socket_schedule_peer(void);
|
||||
void socket_config_address(void);
|
||||
void socket_unconfigure_address(void);
|
||||
void socket_update_link_state(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -37,7 +37,10 @@ using Socket_queue = Fifo<Lx_call>;
|
||||
|
||||
struct Statics
|
||||
{
|
||||
genode_socket_wakeup *wakeup_remote;
|
||||
genode_socket_wakeup *wakeup_remote { nullptr };
|
||||
genode_socket_config config{ };
|
||||
bool address_configured { false };
|
||||
bool address_valid { false };
|
||||
};
|
||||
|
||||
|
||||
@ -433,6 +436,39 @@ struct Lx_sock_release : Lx_call
|
||||
};
|
||||
|
||||
|
||||
struct Lx_nic_link_state : Lx_call
|
||||
{
|
||||
bool state { false };
|
||||
|
||||
Lx_nic_link_state(genode_socket_handle &handle) : Lx_call(handle)
|
||||
{
|
||||
schedule();
|
||||
}
|
||||
|
||||
void execute() override
|
||||
{
|
||||
state = lx_nic_client_link_state();
|
||||
finished = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Lx_nic_update_link_state : Lx_call
|
||||
{
|
||||
bool state { false };
|
||||
|
||||
Lx_nic_update_link_state(genode_socket_handle &handle) : Lx_call(handle)
|
||||
{
|
||||
schedule();
|
||||
}
|
||||
|
||||
void execute() override
|
||||
{
|
||||
state = lx_nic_client_update_link_state();
|
||||
finished = true;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Dispatch socket calls in Linux task
|
||||
*/
|
||||
@ -485,18 +521,38 @@ static void _destroy_handle(genode_socket_handle *handle)
|
||||
}
|
||||
|
||||
|
||||
static genode_socket_handle _disposable_handle()
|
||||
{
|
||||
return {
|
||||
.sock = nullptr,
|
||||
.task = lx_socket_dispatch_root(),
|
||||
.queue = static_cast<Socket_queue *>(lx_socket_dispatch_queue()),
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Genode socket C-API
|
||||
*/
|
||||
|
||||
void genode_socket_config_address(struct genode_socket_config *config)
|
||||
{
|
||||
genode_socket_handle handle = {
|
||||
.task = lx_socket_dispatch_root(),
|
||||
.queue = static_cast<Socket_queue *>(lx_socket_dispatch_queue()),
|
||||
};
|
||||
|
||||
Lx_address addr { handle, config };
|
||||
statics().config = *config;
|
||||
statics().address_valid = true;
|
||||
|
||||
genode_socket_handle handle { _disposable_handle() };
|
||||
Lx_nic_link_state link { handle };
|
||||
if (link.state) {
|
||||
/* local implementation here */
|
||||
statics().address_configured = false;
|
||||
socket_config_address();
|
||||
}
|
||||
|
||||
/* wait for link state change to trigger ip configuration */
|
||||
while (!statics().address_configured) {
|
||||
genode_socket_wakeup_remote();
|
||||
genode_socket_wait_for_progress();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -505,9 +561,6 @@ extern "C" unsigned int ic_netmask;
|
||||
extern "C" unsigned int ic_gateway;
|
||||
extern "C" unsigned int ic_nameservers[1];
|
||||
|
||||
//XXX: implement link state
|
||||
bool ic_link_state = true;
|
||||
|
||||
void genode_socket_config_info(struct genode_socket_info *info)
|
||||
{
|
||||
if (!info) return;
|
||||
@ -515,16 +568,16 @@ void genode_socket_config_info(struct genode_socket_info *info)
|
||||
info->netmask = ic_netmask;
|
||||
info->gateway = ic_gateway;
|
||||
info->nameserver = ic_nameservers[0];
|
||||
info->link_state = ic_link_state;
|
||||
|
||||
genode_socket_handle handle { _disposable_handle() };
|
||||
Lx_nic_link_state link { handle };
|
||||
info->link_state = link.state;
|
||||
}
|
||||
|
||||
|
||||
void genode_socket_configure_mtu(unsigned mtu)
|
||||
{
|
||||
genode_socket_handle handle = {
|
||||
.task = lx_socket_dispatch_root(),
|
||||
.queue = static_cast<Socket_queue *>(lx_socket_dispatch_queue()),
|
||||
};
|
||||
|
||||
genode_socket_handle handle { _disposable_handle() };
|
||||
Lx_mtu addr { handle, mtu };
|
||||
}
|
||||
|
||||
@ -708,11 +761,43 @@ void genode_socket_register_wakeup(struct genode_socket_wakeup *remote)
|
||||
|
||||
|
||||
/*
|
||||
* Called by net_driver.c
|
||||
* local C-interface
|
||||
*/
|
||||
void lx_nic_client_schedule_peer(void)
|
||||
|
||||
void socket_schedule_peer(void)
|
||||
{
|
||||
if (statics().wakeup_remote && statics().wakeup_remote->callback) {
|
||||
statics().wakeup_remote->callback(statics().wakeup_remote->data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void socket_config_address(void)
|
||||
{
|
||||
if (statics().address_configured || statics().address_valid == false)
|
||||
return;
|
||||
|
||||
genode_socket_handle handle { _disposable_handle() };
|
||||
|
||||
Lx_address addr { handle, &statics().config };
|
||||
|
||||
statics().address_configured = true;
|
||||
}
|
||||
|
||||
|
||||
void socket_unconfigure_address(void)
|
||||
{
|
||||
statics().address_configured = false;
|
||||
}
|
||||
|
||||
|
||||
void socket_update_link_state(void)
|
||||
{
|
||||
genode_socket_handle handle { _disposable_handle() };
|
||||
Lx_nic_update_link_state link { handle };
|
||||
|
||||
if (link.state)
|
||||
socket_config_address();
|
||||
else
|
||||
statics().address_configured = false;
|
||||
}
|
||||
|
@ -580,13 +580,6 @@ void * mtree_load(struct maple_tree * mt,unsigned long index)
|
||||
}
|
||||
|
||||
|
||||
extern void netdev_unregister_kobject(struct net_device * ndev);
|
||||
void netdev_unregister_kobject(struct net_device * ndev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/pipe_fs_i.h>
|
||||
|
||||
const struct pipe_buf_operations nosteal_pipe_buf_ops;
|
||||
|
@ -471,13 +471,6 @@ void * mtree_load(struct maple_tree * mt,unsigned long index)
|
||||
}
|
||||
|
||||
|
||||
extern void netdev_unregister_kobject(struct net_device * ndev);
|
||||
void netdev_unregister_kobject(struct net_device * ndev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/pipe_fs_i.h>
|
||||
|
||||
const struct pipe_buf_operations nosteal_pipe_buf_ops;
|
||||
|
@ -588,13 +588,6 @@ void * mtree_load(struct maple_tree * mt,unsigned long index)
|
||||
}
|
||||
|
||||
|
||||
extern void netdev_unregister_kobject(struct net_device * ndev);
|
||||
void netdev_unregister_kobject(struct net_device * ndev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/pipe_fs_i.h>
|
||||
|
||||
const struct pipe_buf_operations nosteal_pipe_buf_ops;
|
||||
|
@ -543,13 +543,6 @@ void * mtree_load(struct maple_tree * mt,unsigned long index)
|
||||
}
|
||||
|
||||
|
||||
extern void netdev_unregister_kobject(struct net_device * ndev);
|
||||
void netdev_unregister_kobject(struct net_device * ndev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/pipe_fs_i.h>
|
||||
|
||||
const struct pipe_buf_operations nosteal_pipe_buf_ops;
|
||||
|
@ -548,13 +548,6 @@ void * mtree_load(struct maple_tree * mt,unsigned long index)
|
||||
}
|
||||
|
||||
|
||||
extern void netdev_unregister_kobject(struct net_device * ndev);
|
||||
void netdev_unregister_kobject(struct net_device * ndev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/pipe_fs_i.h>
|
||||
|
||||
const struct pipe_buf_operations nosteal_pipe_buf_ops;
|
||||
|
Loading…
x
Reference in New Issue
Block a user