From 4f084d1f9ed7d609a8f25d16d30fb1b786fb6dcd Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Tue, 15 Oct 2024 11:04:34 +0200 Subject: [PATCH] lx_emul: unify NIC uplink binding Fix genodelabs/genode#5361 --- repos/dde_linux/src/driver/usb_net/lx_user.c | 227 +-------------- repos/dde_linux/src/driver/usb_net/main.cc | 10 +- repos/dde_linux/src/driver/usb_net/target.inc | 1 + repos/dde_linux/src/include/lx_emul/nic.h | 31 +++ repos/dde_linux/src/lib/lx_emul/nic.c | 258 ++++++++++++++++++ repos/pc/src/driver/nic/pc/lx_user.c | 205 +------------- repos/pc/src/driver/nic/pc/main.cc | 9 +- repos/pc/src/driver/nic/pc/rtnetlink.c | 11 + repos/pc/src/driver/nic/pc/target.inc | 1 + 9 files changed, 319 insertions(+), 434 deletions(-) create mode 100644 repos/dde_linux/src/include/lx_emul/nic.h create mode 100644 repos/dde_linux/src/lib/lx_emul/nic.c diff --git a/repos/dde_linux/src/driver/usb_net/lx_user.c b/repos/dde_linux/src/driver/usb_net/lx_user.c index d038379a95..e5d7a3698f 100644 --- a/repos/dde_linux/src/driver/usb_net/lx_user.c +++ b/repos/dde_linux/src/driver/usb_net/lx_user.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -30,230 +31,17 @@ struct task_struct *lx_user_new_usb_task(int (*func)(void*), void *args, } -static struct genode_uplink *dev_genode_uplink(struct net_device *dev) -{ - return (struct genode_uplink *)dev->ifalias; -} - - -struct genode_uplink_rx_context -{ - struct net_device *dev; -}; - - -struct genode_uplink_tx_packet_context -{ - struct sk_buff *skb; -}; - - -static unsigned long uplink_tx_packet_content(struct genode_uplink_tx_packet_context *ctx, - char *dst, unsigned long dst_len) -{ - struct sk_buff * const skb = ctx->skb; - - skb_push(skb, ETH_HLEN); - - if (dst_len < skb->len) { - printk("uplink_tx_packet_content: packet exceeds uplink packet size\n"); - memset(dst, 0, dst_len); - return 0; - } - - skb_copy_from_linear_data(skb, dst, skb->len); - - /* clear unused part of the destination buffer */ - memset(dst + skb->len, 0, dst_len - skb->len); - - return skb->len; -} - - -static rx_handler_result_t handle_rx(struct sk_buff **pskb) -{ - struct sk_buff *skb = *pskb; - struct net_device *dev = skb->dev; - struct genode_uplink_tx_packet_context ctx = { .skb = skb }; - - /* if uplink still exists */ - if (dev->ifalias) { - bool progress = genode_uplink_tx_packet(dev_genode_uplink(dev), - uplink_tx_packet_content, - &ctx); - if (!progress) - printk("handle_rx: uplink saturated, dropping packet\n"); - } - - kfree_skb(skb); - return RX_HANDLER_CONSUMED; -} - - -/** - * Create Genode uplink for given net device - * - * The uplink is registered at the dev->ifalias pointer. - */ -static void handle_create_uplink(struct net_device *dev) -{ - struct genode_uplink_args args; - - if (dev_genode_uplink(dev)) - return; - - if (!netif_carrier_ok(dev)) - return; - - printk("create uplink for net device %s\n", &dev->name[0]); - - memset(&args, 0, sizeof(args)); - - if (dev->addr_len != sizeof(args.mac_address)) { - printk("error: net device has unexpected addr_len %u\n", dev->addr_len); - return; - } - - { - unsigned i; - for (i = 0; i < dev->addr_len; i++) - args.mac_address[i] = dev->dev_addr[i]; - } - - args.label = &dev->name[0]; - - dev->ifalias = (struct dev_ifalias *)genode_uplink_create(&args); -} - - -static void handle_destroy_uplink(struct net_device *dev) -{ - struct genode_uplink *uplink = dev_genode_uplink(dev); - - if (!uplink) - return; - - if (netif_carrier_ok(dev)) - return; - - printk("destroy uplink for net device %s\n", &dev->name[0]); - genode_uplink_destroy(uplink); - - dev->ifalias = NULL; -} - - -static genode_uplink_rx_result_t uplink_rx_one_packet(struct genode_uplink_rx_context *ctx, - char const *ptr, unsigned long len) -{ - struct sk_buff *skb = alloc_skb(len, GFP_KERNEL); - - if (!skb) { - printk("alloc_skb failed\n"); - return GENODE_UPLINK_RX_RETRY; - } - - skb_copy_to_linear_data(skb, ptr, len); - skb_put(skb, len); - skb->dev = ctx->dev; - - if (dev_queue_xmit(skb) < 0) { - printk("lx_user: failed to xmit packet\n"); - return GENODE_UPLINK_RX_REJECTED; - } - - return GENODE_UPLINK_RX_ACCEPTED; -} - - -/* - * custom MAC address - */ -bool use_mac_address; -unsigned char mac_address[6]; -static bool mac_address_configured = false; - -static void handle_mac_address(struct net_device *dev) -{ - int err; - struct sockaddr addr; - struct genode_mac_address dev_addr; - - if (mac_address_configured || !netif_device_present(dev)) return; - - if (use_mac_address) { - memcpy(&addr.sa_data, mac_address, ETH_ALEN); - addr.sa_family = dev->type; - err = dev_set_mac_address(dev, &addr, NULL); - if (err < 0) - printk("Warning: Could not set configured MAC address: %pM (err=%d)\n", - mac_address, err); - } - - memcpy(dev_addr.addr, dev->dev_addr, sizeof(dev_addr)); - genode_mac_address_register(dev->name, dev_addr); - - mac_address_configured =true; -} - - -static int network_loop(void *arg) -{ - for (;;) { - - struct net_device *dev; - - for_each_netdev(&init_net, dev) { - - handle_mac_address(dev); - - /* enable link sensing, repeated calls are handled by testing IFF_UP */ - dev_open(dev, 0); - - /* install rx handler once */ - if (!netdev_is_rx_handler_busy(dev)) - netdev_rx_handler_register(dev, handle_rx, NULL); - - /* respond to cable plug/unplug */ - handle_create_uplink(dev); - handle_destroy_uplink(dev); - - /* transmit packets received from the uplink session */ - if (netif_carrier_ok(dev)) { - - struct genode_uplink_rx_context ctx = { .dev = dev }; - - while (genode_uplink_rx(dev_genode_uplink(dev), - uplink_rx_one_packet, - &ctx)); - } - }; - - /* block until lx_emul_task_unblock */ - lx_emul_task_schedule(true); - } - return 0; -} - - -static struct task_struct *net_task; - void lx_user_init(void) { - pid_t pid; - lx_emul_usb_client_init(); - - pid = kernel_thread(network_loop, NULL, "network_loop", - CLONE_FS | CLONE_FILES); - net_task = find_task_by_pid_ns(pid, NULL); + lx_emul_nic_init(); } void lx_user_handle_io(void) { lx_emul_usb_client_ticker(); - if (net_task) lx_emul_task_unblock(net_task); + lx_emul_nic_handle_io(); } @@ -269,11 +57,10 @@ void rtmsg_ifinfo(int type, struct net_device * dev, unsigned int change, gfp_t flags, u32 portid, const struct nlmsghdr *nlh) { - /* trigger handle_create_uplink / handle_destroy_uplink */ - if (net_task) lx_emul_task_unblock(net_task); + lx_emul_nic_handle_io(); if (force_uplink_destroy) { - struct genode_uplink *uplink = dev_genode_uplink(dev); + struct genode_uplink *uplink = (struct genode_uplink *)dev->ifalias; printk("force destroy uplink for net device %s\n", &dev->name[0]); genode_uplink_destroy(uplink); force_uplink_destroy = false; @@ -284,7 +71,9 @@ void rtmsg_ifinfo(int type, struct net_device * dev, void lx_emul_usb_client_device_unregister_callback(struct usb_device *) { force_uplink_destroy = true; - mac_address_configured = false; + + /* set mac as unconfigured by setting nothing */ + lx_emul_nic_set_mac_address(NULL, 0); } diff --git a/repos/dde_linux/src/driver/usb_net/main.cc b/repos/dde_linux/src/driver/usb_net/main.cc index 8ae8a8d458..497afb9980 100644 --- a/repos/dde_linux/src/driver/usb_net/main.cc +++ b/repos/dde_linux/src/driver/usb_net/main.cc @@ -23,15 +23,13 @@ #include #include #include +#include /* C-interface */ #include using namespace Genode; -extern bool use_mac_address; -extern unsigned char mac_address[6]; - struct Main { Env &env; @@ -90,12 +88,10 @@ struct Main usb_config = config_rom.xml().attribute_value("configuration", 0ul); /* retrieve possible MAC */ - use_mac_address = config_rom.xml().has_attribute("mac"); - if (use_mac_address) { + if (config_rom.xml().has_attribute("mac")) { auto const mac = config_rom.xml().attribute_value("mac", Nic::Mac_address{}); - mac.copy(mac_address); - use_mac_address = true; log("Trying to use configured mac: ", mac); + lx_emul_nic_set_mac_address(mac.addr, sizeof(mac.addr)); } } }; diff --git a/repos/dde_linux/src/driver/usb_net/target.inc b/repos/dde_linux/src/driver/usb_net/target.inc index 7fbee1840b..08d2559ef0 100644 --- a/repos/dde_linux/src/driver/usb_net/target.inc +++ b/repos/dde_linux/src/driver/usb_net/target.inc @@ -8,6 +8,7 @@ SRC_C += dummies.c \ lx_emul.c \ lx_user.c +SRC_C += lx_emul/nic.c SRC_C += lx_emul/virt/shadow/drivers/usb/core/buffer.c SRC_C += lx_emul/virt/shadow/drivers/usb/core/hcd.c SRC_C += lx_emul/virt/usb_client.c diff --git a/repos/dde_linux/src/include/lx_emul/nic.h b/repos/dde_linux/src/include/lx_emul/nic.h new file mode 100644 index 0000000000..307b2835ee --- /dev/null +++ b/repos/dde_linux/src/include/lx_emul/nic.h @@ -0,0 +1,31 @@ +/* + * \brief Lx_emul support for NICs + * \author Stefan Kalkowski + * \date 2024-10-15 + */ + +/* + * Copyright (C) 2024 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#ifndef _LX_EMUL__NIC_H_ +#define _LX_EMUL__NIC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +extern void lx_emul_nic_init(void); +extern void lx_emul_nic_handle_io(void); +extern void lx_emul_nic_set_mac_address(const unsigned char *mac, + unsigned long size); + +#ifdef __cplusplus +} +#endif + +#endif /* _LX_EMUL__USB_H_ */ + diff --git a/repos/dde_linux/src/lib/lx_emul/nic.c b/repos/dde_linux/src/lib/lx_emul/nic.c new file mode 100644 index 0000000000..2f5d702c32 --- /dev/null +++ b/repos/dde_linux/src/lib/lx_emul/nic.c @@ -0,0 +1,258 @@ +/* + * \brief PC Ethernet driver + * \author Norman Feske + * \author Christian Helmuth + * \author Stefan Kalkowski + * \date 2024-10-15 + */ + +/* + * Copyright (C) 2024 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#include +#include +#include +#include +#include + + +static struct genode_uplink *dev_genode_uplink(struct net_device *dev) +{ + return (struct genode_uplink *)dev->ifalias; +} + + +struct genode_uplink_rx_context +{ + struct net_device *dev; +}; + + +struct genode_uplink_tx_packet_context +{ + struct sk_buff *skb; +}; + + +static unsigned long uplink_tx_packet_content(struct genode_uplink_tx_packet_context *ctx, + char *dst, unsigned long dst_len) +{ + struct sk_buff * const skb = ctx->skb; + + skb_push(skb, ETH_HLEN); + + if (dst_len < skb->len) { + printk("uplink_tx_packet_content: packet exceeds uplink packet size\n"); + memset(dst, 0, dst_len); + return 0; + } + + skb_copy_from_linear_data(skb, dst, skb->len); + + /* clear unused part of the destination buffer */ + memset(dst + skb->len, 0, dst_len - skb->len); + + return skb->len; +} + + +static rx_handler_result_t handle_rx(struct sk_buff **pskb) +{ + struct sk_buff *skb = *pskb; + struct net_device *dev = skb->dev; + struct genode_uplink_tx_packet_context ctx = { .skb = skb }; + struct genode_uplink *uplink = dev_genode_uplink(dev); + + if (!uplink) + return RX_HANDLER_PASS; + + { + bool progress = genode_uplink_tx_packet(uplink, + uplink_tx_packet_content, + &ctx); + if (!progress) + printk("handle_rx: uplink saturated, dropping packet\n"); + } + + kfree_skb(skb); + return RX_HANDLER_CONSUMED; +} + + +/** + * Create Genode uplink for given net device + * + * The uplink is registered at the dev->ifalias pointer. + */ +static void handle_create_uplink(struct net_device *dev) +{ + struct genode_uplink_args args; + + if (dev_genode_uplink(dev)) + return; + + if (!netif_carrier_ok(dev)) + return; + + printk("create uplink for net device %s\n", &dev->name[0]); + + memset(&args, 0, sizeof(args)); + + if (dev->addr_len != sizeof(args.mac_address)) { + printk("error: net device has unexpected addr_len %u\n", dev->addr_len); + return; + } + + { + unsigned i; + for (i = 0; i < dev->addr_len; i++) + args.mac_address[i] = dev->dev_addr[i]; + } + + args.label = &dev->name[0]; + + dev->ifalias = (struct dev_ifalias *)genode_uplink_create(&args); +} + + +static void handle_destroy_uplink(struct net_device *dev) +{ + struct genode_uplink *uplink = dev_genode_uplink(dev); + + if (!uplink) + return; + + if (netif_carrier_ok(dev)) + return; + + genode_uplink_destroy(uplink); + + dev->ifalias = NULL; +} + + +static genode_uplink_rx_result_t uplink_rx_one_packet(struct genode_uplink_rx_context *ctx, + char const *ptr, unsigned long len) +{ + struct sk_buff *skb = alloc_skb(len, GFP_KERNEL); + + if (!skb) { + printk("alloc_skb failed\n"); + return GENODE_UPLINK_RX_RETRY; + } + + skb_copy_to_linear_data(skb, ptr, len); + skb_put(skb, len); + skb->dev = ctx->dev; + + if (dev_queue_xmit(skb) < 0) { + printk("lx_user: failed to xmit packet\n"); + return GENODE_UPLINK_RX_REJECTED; + } + + return GENODE_UPLINK_RX_ACCEPTED; +} + + +/* + * custom MAC address + */ +static unsigned char mac_address[6]; +static bool mac_address_configured = false; + +static void handle_mac_address(struct net_device *dev) +{ + int err; + struct sockaddr addr; + struct genode_mac_address dev_addr; + + if (mac_address_configured || !netif_device_present(dev)) return; + + if (mac_address[0] || mac_address[1] || mac_address[2] || + mac_address[3] || mac_address[4] || mac_address[5]) { + memcpy(&addr.sa_data, mac_address, ETH_ALEN); + addr.sa_family = dev->type; + err = dev_set_mac_address(dev, &addr, NULL); + if (err < 0) + printk("Warning: Could not set configured MAC address: %pM (err=%d)\n", + mac_address, err); + } + + memcpy(dev_addr.addr, dev->dev_addr, sizeof(dev_addr)); + genode_mac_address_register(dev->name, dev_addr); + + mac_address_configured =true; +} + + +static int nic_task_function(void *arg) +{ + for (;;) { + + struct net_device *dev; + + for_each_netdev(&init_net, dev) { + + handle_mac_address(dev); + + /* enable link sensing, repeated calls are handled by testing IFF_UP */ + dev_open(dev, 0); + + /* install rx handler once */ + if (!netdev_is_rx_handler_busy(dev)) + netdev_rx_handler_register(dev, handle_rx, NULL); + + /* respond to cable plug/unplug */ + handle_create_uplink(dev); + handle_destroy_uplink(dev); + + /* transmit packets received from the uplink session */ + if (netif_carrier_ok(dev)) { + + struct genode_uplink_rx_context ctx = { .dev = dev }; + + while (genode_uplink_rx(dev_genode_uplink(dev), + uplink_rx_one_packet, + &ctx)); + } + }; + + /* block until lx_emul_task_unblock */ + lx_emul_task_schedule(true); + } + return 0; +} + + +static struct task_struct *nic_task_struct_ptr; + + +void lx_emul_nic_init(void) +{ + pid_t pid; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,3,0) + pid = kernel_thread(nic_task_function, NULL, "user_task", CLONE_FS | CLONE_FILES); +#else + pid = kernel_thread(nic_task_function, NULL, CLONE_FS | CLONE_FILES); +#endif + + nic_task_struct_ptr = find_task_by_pid_ns(pid, NULL); +} + + +void lx_emul_nic_handle_io(void) +{ + if (nic_task_struct_ptr) lx_emul_task_unblock(nic_task_struct_ptr); +} + + +void lx_emul_nic_set_mac_address(const unsigned char *mac, unsigned long size) +{ + memcpy(mac_address, mac, min(sizeof(mac_address), size)); + mac_address_configured = false; +} diff --git a/repos/pc/src/driver/nic/pc/lx_user.c b/repos/pc/src/driver/nic/pc/lx_user.c index 5ecfaa43a6..3dbbe4f846 100644 --- a/repos/pc/src/driver/nic/pc/lx_user.c +++ b/repos/pc/src/driver/nic/pc/lx_user.c @@ -11,214 +11,17 @@ * version 2. */ -#include -#include #include -#include -#include - - -static struct genode_uplink *dev_genode_uplink(struct net_device *dev) -{ - return (struct genode_uplink *)dev->ifalias; -} - - -struct genode_uplink_rx_context -{ - struct net_device *dev; -}; - - -struct genode_uplink_tx_packet_context -{ - struct sk_buff *skb; -}; - - -static unsigned long uplink_tx_packet_content(struct genode_uplink_tx_packet_context *ctx, - char *dst, unsigned long dst_len) -{ - struct sk_buff * const skb = ctx->skb; - - skb_push(skb, ETH_HLEN); - - if (dst_len < skb->len) { - printk("uplink_tx_packet_content: packet exceeds uplink packet size\n"); - memset(dst, 0, dst_len); - return 0; - } - - skb_copy_from_linear_data(skb, dst, skb->len); - - /* clear unused part of the destination buffer */ - memset(dst + skb->len, 0, dst_len - skb->len); - - return skb->len; -} - - -static rx_handler_result_t handle_rx(struct sk_buff **pskb) -{ - struct sk_buff *skb = *pskb; - struct net_device *dev = skb->dev; - struct genode_uplink_tx_packet_context ctx = { .skb = skb }; - struct genode_uplink *uplink = dev_genode_uplink(dev); - - if (!uplink) - return RX_HANDLER_PASS; - - { - bool progress = genode_uplink_tx_packet(uplink, - uplink_tx_packet_content, - &ctx); - if (!progress) - printk("handle_rx: uplink saturated, dropping packet\n"); - } - - kfree_skb(skb); - return RX_HANDLER_CONSUMED; -} - - -/** - * Create Genode uplink for given net device - * - * The uplink is registered at the dev->ifalias pointer. - */ -static void handle_create_uplink(struct net_device *dev) -{ - struct genode_uplink_args args; - - if (dev_genode_uplink(dev)) - return; - - if (!netif_carrier_ok(dev)) - return; - - printk("create uplink for net device %s\n", &dev->name[0]); - - memset(&args, 0, sizeof(args)); - - if (dev->addr_len != sizeof(args.mac_address)) { - printk("error: net device has unexpected addr_len %u\n", dev->addr_len); - return; - } - - { - unsigned i; - for (i = 0; i < dev->addr_len; i++) - args.mac_address[i] = dev->dev_addr[i]; - } - - args.label = &dev->name[0]; - - dev->ifalias = (struct dev_ifalias *)genode_uplink_create(&args); -} - - -static void handle_destroy_uplink(struct net_device *dev) -{ - struct genode_uplink *uplink = dev_genode_uplink(dev); - - if (!uplink) - return; - - if (netif_carrier_ok(dev)) - return; - - genode_uplink_destroy(uplink); - - dev->ifalias = NULL; -} - - -static genode_uplink_rx_result_t uplink_rx_one_packet(struct genode_uplink_rx_context *ctx, - char const *ptr, unsigned long len) -{ - struct sk_buff *skb = alloc_skb(len, GFP_KERNEL); - - if (!skb) { - printk("alloc_skb failed\n"); - return GENODE_UPLINK_RX_RETRY; - } - - skb_copy_to_linear_data(skb, ptr, len); - skb_put(skb, len); - skb->dev = ctx->dev; - - if (dev_queue_xmit(skb) < 0) { - printk("lx_user: failed to xmit packet\n"); - return GENODE_UPLINK_RX_REJECTED; - } - - return GENODE_UPLINK_RX_ACCEPTED; -} - - -static int user_task_function(void *arg) -{ - for (;;) { - - struct net_device *dev; - - for_each_netdev(&init_net, dev) { - struct genode_mac_address dev_addr; - - /* enable link sensing, repeated calls are handled by testing IFF_UP */ - dev_open(dev, 0); - - memcpy(dev_addr.addr, dev->dev_addr, sizeof(dev_addr)); - genode_mac_address_register(dev->name, dev_addr); - - /* install rx handler once */ - if (!netdev_is_rx_handler_busy(dev)) - netdev_rx_handler_register(dev, handle_rx, NULL); - - /* respond to cable plug/unplug */ - handle_create_uplink(dev); - handle_destroy_uplink(dev); - - /* transmit packets received from the uplink session */ - if (netif_carrier_ok(dev)) { - - struct genode_uplink_rx_context ctx = { .dev = dev }; - - while (genode_uplink_rx(dev_genode_uplink(dev), - uplink_rx_one_packet, - &ctx)); - } - }; - - /* block until lx_emul_task_unblock */ - lx_emul_task_schedule(true); - } - return 0; -} - - -struct task_struct *user_task_struct_ptr; /* used by 'Main' for lx_emul_task_unblock */ +#include void lx_user_init(void) { - pid_t pid; - - pid = kernel_thread(user_task_function, NULL, "user_task", CLONE_FS | CLONE_FILES); - - user_task_struct_ptr = find_task_by_pid_ns(pid, NULL); + lx_emul_nic_init(); } -#include - -/* - * Called whenever the link state changes - */ -void rtmsg_ifinfo(int type, struct net_device * dev, unsigned int change, gfp_t flags, - u32 portid, const struct nlmsghdr *nlh) +void lx_user_handle_io(void) { - /* trigger handle_create_uplink / handle_destroy_uplink */ - if (user_task_struct_ptr) - lx_emul_task_unblock(user_task_struct_ptr); + lx_emul_nic_handle_io(); } diff --git a/repos/pc/src/driver/nic/pc/main.cc b/repos/pc/src/driver/nic/pc/main.cc index f81f6e0dda..22d57541e5 100644 --- a/repos/pc/src/driver/nic/pc/main.cc +++ b/repos/pc/src/driver/nic/pc/main.cc @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include @@ -26,8 +26,6 @@ namespace Pc { } -extern task_struct *user_task_struct_ptr; - struct Pc::Main { Env &_env; @@ -52,11 +50,8 @@ struct Pc::Main void _handle_signal() { - if (user_task_struct_ptr) - lx_emul_task_unblock(user_task_struct_ptr); - + lx_user_handle_io(); Lx_kit::env().scheduler.execute(); - genode_uplink_notify_peers(); } diff --git a/repos/pc/src/driver/nic/pc/rtnetlink.c b/repos/pc/src/driver/nic/pc/rtnetlink.c index 78c956d90d..9dac867eae 100644 --- a/repos/pc/src/driver/nic/pc/rtnetlink.c +++ b/repos/pc/src/driver/nic/pc/rtnetlink.c @@ -12,6 +12,7 @@ */ #include +#include #include #include @@ -56,3 +57,13 @@ void rtnl_unlock(void) { netdev_run_todo(); } + + +/* + * Called whenever the link state changes + */ +void rtmsg_ifinfo(int type, struct net_device * dev, unsigned int change, gfp_t flags, + u32 portid, const struct nlmsghdr *nlh) +{ + lx_emul_nic_handle_io(); +} diff --git a/repos/pc/src/driver/nic/pc/target.inc b/repos/pc/src/driver/nic/pc/target.inc index 3fd76b75d6..94761b45c6 100644 --- a/repos/pc/src/driver/nic/pc/target.inc +++ b/repos/pc/src/driver/nic/pc/target.inc @@ -7,6 +7,7 @@ SRC_CC += main.cc SRC_C += dummies.c SRC_C += lx_emul.c SRC_C += lx_emul/common_dummies.c +SRC_C += lx_emul/nic.c SRC_C += lx_user.c SRC_C += rtnetlink.c