diff --git a/app/zynq-common/init.c b/app/zynq-common/init.c index 8e056ea3..c4774666 100644 --- a/app/zynq-common/init.c +++ b/app/zynq-common/init.c @@ -172,14 +172,15 @@ static void zynq_common_target_init(uint level) { sysparam_read("net0.ip_mask", &ip_mask, sizeof(ip_mask)); sysparam_read("net0.ip_gateway", &ip_gateway, sizeof(ip_gateway)); - minip_set_macaddr(mac_addr); gem_set_macaddr(mac_addr); + minip_set_eth(gem_send_raw_pkt, NULL, mac_addr); + if (!use_dhcp && ip_addr != IPV4_NONE) { - minip_init(gem_send_raw_pkt, NULL, ip_addr, ip_mask, ip_gateway); + minip_start_static(ip_addr, ip_mask, ip_gateway); } else { /* Configure IP stack and hook to the driver */ - minip_init_dhcp(gem_send_raw_pkt, NULL); + minip_start_dhcp(); } gem_set_callback(minip_rx_driver_callback); #endif diff --git a/dev/net/e1000/e1000.cpp b/dev/net/e1000/e1000.cpp index 9a007704..6a826658 100644 --- a/dev/net/e1000/e1000.cpp +++ b/dev/net/e1000/e1000.cpp @@ -60,6 +60,8 @@ public: bool is_e1000e() const { return id_feat_->e1000e; } + const uint8_t *mac_addr() const { return mac_addr_; } + private: static const size_t rxring_len = 64; static const size_t txring_len = 64; @@ -428,10 +430,6 @@ status_t e1000::init_device(pci_location_t loc, const e1000_id_features *id) { } LTRACEF("IRQ number %#x\n", irq_base); - // set up minip's macaddr - // TODO: move to something smarter - minip_set_macaddr(mac_addr_); - unmask_interrupt(irq_base); // set up the rx ring @@ -513,9 +511,7 @@ status_t e1000::init_device(pci_location_t loc, const e1000_id_features *id) { return NO_ERROR; } -// XXX REMOVE HACK -extern "C" -int e1000_tx(pktbuf_t *p) { +static int e1000_tx(pktbuf_t *p) { if (the_e) { the_e->tx(p); } @@ -523,6 +519,16 @@ int e1000_tx(pktbuf_t *p) { return NO_ERROR; } +extern "C" +status_t e1000_register_with_minip() { + if (the_e) { + minip_set_eth(e1000_tx, the_e, the_e->mac_addr()); + return NO_ERROR; + } + + return ERR_NOT_FOUND; +} + static void e1000_init(uint level) { LTRACE_ENTRY; diff --git a/docs/lk_tap.txt b/docs/lk_tap.txt new file mode 100644 index 00000000..5cfac38e --- /dev/null +++ b/docs/lk_tap.txt @@ -0,0 +1,11 @@ +# Setting up a tun/tap network for qemu +sudo ip tuntap add mode tap user $USER name qemu0 +sudo ip link set qemu0 up + +# manually making bridge +sudo brctl addbr br0 +sudo brctl addif br0 qemu0 +sudo brctl addif br0 +sudo ip link set br0 up + +# alternatively using the network config to create the bridge and merge it with particular vlan diff --git a/lib/minip/dhcp.cpp b/lib/minip/dhcp.cpp index 64a87a51..1d185617 100644 --- a/lib/minip/dhcp.cpp +++ b/lib/minip/dhcp.cpp @@ -322,6 +322,9 @@ done: } state_ = CONFIGURED; configured_ = true; + + // signal that minip is ready to be used + minip_set_configured(); } } } @@ -375,9 +378,7 @@ status_t dhcp::start() { } // anonymous namespace -void minip_init_dhcp(tx_func_t tx_func, void *tx_arg) { - minip_init(tx_func, tx_arg, IPV4_NONE, IPV4_NONE, IPV4_NONE); - +void minip_start_dhcp() { static dhcp d; d.start(); } diff --git a/lib/minip/include/lib/minip.h b/lib/minip/include/lib/minip.h index bfee41cc..8ce54916 100644 --- a/lib/minip/include/lib/minip.h +++ b/lib/minip/include/lib/minip.h @@ -28,12 +28,21 @@ typedef int (*tx_func_t)(pktbuf_t *p); typedef void (*udp_callback_t)(void *data, size_t len, uint32_t srcaddr, uint16_t srcport, void *arg); -/* initialize minip with static configuration */ -void minip_init(tx_func_t tx_func, void *tx_arg, - uint32_t ip, uint32_t netmask, uint32_t gateway); +/* initialize and start minip with static configuration */ +void minip_start_static(uint32_t ip, uint32_t netmask, uint32_t gateway); -/* initialize minip with DHCP configuration */ -void minip_init_dhcp(tx_func_t tx_func, void *tx_arg); +/* initialize and start minip with DHCP configuration + * note: may take a while to have an ip address assigned, check + * for configuration with minip_is_configured() + */ +void minip_start_dhcp(void); + +/* ethernet driver install hook */ +void minip_set_eth(tx_func_t tx_handler, void *tx_arg, const uint8_t *macaddr); + +/* check or wait for minip to be configured */ +bool minip_is_configured(void); +status_t minip_wait_for_configured(lk_time_t timeout); /* packet rx hook to hand to ethernet driver */ void minip_rx_driver_callback(pktbuf_t *p); @@ -49,17 +58,9 @@ void minip_set_netmask(const uint32_t mask); uint32_t minip_get_broadcast(void); // computed from ipaddr & netmask uint32_t minip_get_gateway(void); void minip_set_gateway(const uint32_t addr); - void minip_set_hostname(const char *name); const char *minip_get_hostname(void); - -uint32_t minip_get_broadcast(void); - -uint32_t minip_get_netmask(void); -void minip_set_netmask(const uint32_t netmask); - -uint32_t minip_get_gateway(void); -void minip_set_gateway(const uint32_t gateway); +void minip_set_configured(void); // set by dhcp or static init to signal minip is ready to be used /* udp */ typedef struct udp_socket udp_socket_t; @@ -86,6 +87,7 @@ static inline status_t tcp_accept(tcp_socket_t *listen_socket, tcp_socket_t **ac /* utilities */ void gen_random_mac_address(uint8_t *mac_addr); +uint32_t minip_parse_ipaddr(const char *addr, size_t len); uint32_t minip_parse_ipaddr(const char *addr, size_t len); void printip(uint32_t x); diff --git a/lib/minip/minip.c b/lib/minip/minip.c index 87d1b810..bd21b20f 100644 --- a/lib/minip/minip.c +++ b/lib/minip/minip.c @@ -9,6 +9,7 @@ #include "minip-internal.h" +#include #include #include #include @@ -20,6 +21,8 @@ #include #include #include +#include +#include #include // TODO @@ -36,11 +39,37 @@ static uint8_t minip_mac[6] = {0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC}; static char minip_hostname[32] = ""; +static volatile bool minip_configured = false; +static event_t minip_configured_event = EVENT_INITIAL_VALUE(minip_configured_event, false, 0); + +/* This function is called by minip to send packets */ +tx_func_t minip_tx_handler; +void *minip_tx_arg; + static void dump_mac_address(const uint8_t *mac); static void dump_ipv4_addr(uint32_t addr); +/* if all the important configuration bits are set, signal that we're configured */ +static void check_and_set_configured(void) { + if (minip_ip == IPV4_NONE) return; + if (minip_netmask == IPV4_NONE) return; + if (minip_broadcast == IPV4_BCAST) return; + // minip_gateway doesn't have to be set + if (minip_mac[0] == 0xcc && + minip_mac[1] == 0xcc && + minip_mac[2] == 0xcc && + minip_mac[3] == 0xcc && + minip_mac[4] == 0xcc && + minip_mac[5] == 0xcc) return; + + // we're configured + printf("MINIP: setting configured state\n"); + minip_set_configured(); +} + void minip_set_hostname(const char *name) { strlcpy(minip_hostname, name, sizeof(minip_hostname)); + check_and_set_configured(); } const char *minip_get_hostname(void) { @@ -55,10 +84,6 @@ void minip_get_macaddr(uint8_t *addr) { mac_addr_copy(addr, minip_mac); } -void minip_set_macaddr(const uint8_t *addr) { - mac_addr_copy(minip_mac, addr); -} - uint32_t minip_get_ipaddr(void) { return minip_ip; } @@ -66,6 +91,7 @@ uint32_t minip_get_ipaddr(void) { void minip_set_ipaddr(const uint32_t addr) { minip_ip = addr; compute_broadcast_address(); + check_and_set_configured(); } uint32_t minip_get_broadcast(void) { @@ -79,14 +105,30 @@ uint32_t minip_get_netmask(void) { void minip_set_netmask(const uint32_t netmask) { minip_netmask = netmask; compute_broadcast_address(); + check_and_set_configured(); } uint32_t minip_get_gateway(void) { return minip_gateway; } -void minip_set_gateway(const uint32_t gateway) { - minip_gateway = gateway; +void minip_set_gateway(const uint32_t addr) { + minip_gateway = addr; + // TODO: check that it is reacheable on local network + check_and_set_configured(); +} + +void minip_set_configured(void) { + minip_configured = true; + event_signal(&minip_configured_event, true); +} + +bool minip_is_configured(void) { + return minip_configured; +} + +status_t minip_wait_for_configured(lk_time_t timeout) { + return event_wait_timeout(&minip_configured_event, timeout); } void gen_random_mac_address(uint8_t *mac_addr) { @@ -98,21 +140,24 @@ void gen_random_mac_address(uint8_t *mac_addr) { mac_addr[0] |= (1<<1); } -/* This function is called by minip to send packets */ -tx_func_t minip_tx_handler; -void *minip_tx_arg; - -void minip_init(tx_func_t tx_handler, void *tx_arg, - uint32_t ip, uint32_t mask, uint32_t gateway) { - minip_tx_handler = tx_handler; - minip_tx_arg = tx_arg; - +void minip_start_static(uint32_t ip, uint32_t mask, uint32_t gateway) { minip_set_ipaddr(ip); minip_set_netmask(mask); minip_set_gateway(gateway); +} - arp_cache_init(); - net_timer_init(); +void minip_set_eth(tx_func_t tx_handler, void *tx_arg, const uint8_t *macaddr) { + LTRACEF("handler %p, arg %p, macaddr %p\n", tx_handler, tx_arg, macaddr); + + DEBUG_ASSERT(minip_tx_handler == NULL); + DEBUG_ASSERT(minip_tx_arg == NULL); + // TODO: assert mac address is not already set + + // set up the low level driver handler + minip_tx_handler = tx_handler; + minip_tx_arg = tx_arg; + + mac_addr_copy(minip_mac, macaddr); } static uint16_t ipv4_payload_len(struct ipv4_hdr *pkt) { @@ -507,3 +552,12 @@ void printip_named(const char *s, uint32_t x) { printf("%s ", s); printip(x); } + +// run static initialization +static void minip_init(uint level) { + arp_cache_init(); + net_timer_init(); +} + + +LK_INIT_HOOK(minip, minip_init, LK_INIT_LEVEL_THREADING); diff --git a/platform/pc/platform.c b/platform/pc/platform.c index 9670964f..d324b99f 100644 --- a/platform/pc/platform.c +++ b/platform/pc/platform.c @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -300,9 +301,16 @@ void platform_init(void) { #endif platform_init_mmu_mappings(); +} #if WITH_LIB_MINIP - extern int e1000_tx(pktbuf_t *p); - minip_init_dhcp(e1000_tx, 0); -#endif +void _start_minip(uint level) { + extern status_t e1000_register_with_minip(void); + status_t err = e1000_register_with_minip(); + if (err == NO_ERROR) { + minip_start_dhcp(); + } } + +LK_INIT_HOOK(start_minip, _start_minip, LK_INIT_LEVEL_APPS - 1); +#endif diff --git a/platform/qemu-virt-arm/platform.c b/platform/qemu-virt-arm/platform.c index a31ca84f..81711d5a 100644 --- a/platform/qemu-virt-arm/platform.c +++ b/platform/qemu-virt-arm/platform.c @@ -226,16 +226,16 @@ void platform_init(void) { TRACEF("found virtio networking interface\n"); /* start minip */ - minip_set_macaddr(mac_addr); + minip_set_eth(virtio_net_send_minip_pkt, NULL, mac_addr); __UNUSED uint32_t ip_addr = IPV4(192, 168, 0, 99); __UNUSED uint32_t ip_mask = IPV4(255, 255, 255, 0); __UNUSED uint32_t ip_gateway = IPV4_NONE; - //minip_init(virtio_net_send_minip_pkt, NULL, ip_addr, ip_mask, ip_gateway); - minip_init_dhcp(virtio_net_send_minip_pkt, NULL); - virtio_net_start(); + + //minip_start_static(ip_addr, ip_mask, ip_gateway); + minip_start_dhcp(); } #endif } diff --git a/platform/qemu-virt-m68k/platform.c b/platform/qemu-virt-m68k/platform.c index bd8a3e38..7f4d9107 100644 --- a/platform/qemu-virt-m68k/platform.c +++ b/platform/qemu-virt-m68k/platform.c @@ -106,16 +106,16 @@ void platform_init(void) { TRACEF("found virtio networking interface\n"); /* start minip */ - minip_set_macaddr(mac_addr); + minip_set_eth(virtio_net_send_minip_pkt, NULL, mac_addr); __UNUSED uint32_t ip_addr = IPV4(192, 168, 0, 99); __UNUSED uint32_t ip_mask = IPV4(255, 255, 255, 0); __UNUSED uint32_t ip_gateway = IPV4_NONE; - //minip_init(virtio_net_send_minip_pkt, NULL, ip_addr, ip_mask, ip_gateway); - minip_init_dhcp(virtio_net_send_minip_pkt, NULL); - virtio_net_start(); + + //minip_start_static(ip_addr, ip_mask, ip_gateway); + minip_start_dhcp(); } #endif } diff --git a/platform/qemu-virt-riscv/platform.c b/platform/qemu-virt-riscv/platform.c index cd19273a..51556c4b 100644 --- a/platform/qemu-virt-riscv/platform.c +++ b/platform/qemu-virt-riscv/platform.c @@ -198,16 +198,19 @@ void platform_init(void) { TRACEF("found virtio networking interface\n"); /* start minip */ - minip_set_macaddr(mac_addr); + minip_set_eth(virtio_net_send_minip_pkt, NULL, mac_addr); + virtio_net_start(); + +#if 0 __UNUSED uint32_t ip_addr = IPV4(192, 168, 0, 99); __UNUSED uint32_t ip_mask = IPV4(255, 255, 255, 0); __UNUSED uint32_t ip_gateway = IPV4_NONE; - //minip_init(virtio_net_send_minip_pkt, NULL, ip_addr, ip_mask, ip_gateway); - minip_init_dhcp(virtio_net_send_minip_pkt, NULL); - - virtio_net_start(); + minip_start_static(ip_addr, ip_mask, ip_gateway); +#else + minip_start_dhcp(); +#endif } #endif } diff --git a/target/dartuinoP0/init.c b/target/dartuinoP0/init.c index fd7d6c37..68044eb8 100644 --- a/target/dartuinoP0/init.c +++ b/target/dartuinoP0/init.c @@ -123,13 +123,13 @@ void target_init(void) { eth_init(mac_addr, PHY_KSZ8721); /* start minip */ - minip_set_macaddr(mac_addr); + minip_set_eth(stm32_eth_send_minip_pkt, NULL, mac_addr); uint32_t ip_addr = IPV4(192, 168, 0, 98); uint32_t ip_mask = IPV4(255, 255, 255, 0); uint32_t ip_gateway = IPV4_NONE; - minip_init(stm32_eth_send_minip_pkt, NULL, ip_addr, ip_mask, ip_gateway); + minip_start_static(ip_addr, ip_mask, ip_gateway); #endif #if WITH_LIB_FS_SPIFS diff --git a/target/stm32746g-eval2/init.c b/target/stm32746g-eval2/init.c index bae4507b..535f2616 100644 --- a/target/stm32746g-eval2/init.c +++ b/target/stm32746g-eval2/init.c @@ -67,13 +67,13 @@ void target_init(void) { eth_init(mac_addr, PHY_DP83848); /* start minip */ - minip_set_macaddr(mac_addr); + minip_set_eth(stm32_eth_send_minip_pkt, NULL, mac_addr); uint32_t ip_addr = IPV4(192, 168, 0, 99); uint32_t ip_mask = IPV4(255, 255, 255, 0); uint32_t ip_gateway = IPV4_NONE; - minip_init(stm32_eth_send_minip_pkt, NULL, ip_addr, ip_mask, ip_gateway); + minip_start_static(ip_addr, ip_mask, ip_gateway); #endif TRACE_EXIT; diff --git a/target/stm32f746g-disco/init.c b/target/stm32f746g-disco/init.c index 4bf61ade..6ca41fe4 100644 --- a/target/stm32f746g-disco/init.c +++ b/target/stm32f746g-disco/init.c @@ -64,13 +64,13 @@ void target_init(void) { eth_init(mac_addr, PHY_LAN8742A); /* start minip */ - minip_set_macaddr(mac_addr); + minip_set_eth(stm32_eth_send_minip_pkt, NULL, mac_addr); uint32_t ip_addr = IPV4(192, 168, 0, 98); uint32_t ip_mask = IPV4(255, 255, 255, 0); uint32_t ip_gateway = IPV4_NONE; - minip_init(stm32_eth_send_minip_pkt, NULL, ip_addr, ip_mask, ip_gateway); + minip_start_static(ip_addr, ip_mask, ip_gateway); #endif // start usb