File tree Expand file tree Collapse file tree 10 files changed +347
-13
lines changed Expand file tree Collapse file tree 10 files changed +347
-13
lines changed Original file line number Diff line number Diff line change @@ -45,10 +45,13 @@ ASSERT expect <<DONE
4545 expect "riscv32 GNU/Linux" { send "ip l set eth0 up\n" } timeout { exit 3 }
4646 expect "# " { send "ip a add 192.168.10.2/24 dev eth0\n" }
4747 expect "# " { send "ping -c 3 192.168.10.1\n" }
48- expect "3 packets transmitted, 3 packets received, 0% packet loss" { } timeout { exit 4 }
48+ expect "3 packets transmitted, 3 packets received, 0% packet loss" { } timeout { exit 4 }
4949 } elseif { "$NETDEV " == "user" } {
50- # Test slirp configuration
51- expect "riscv32 GNU/Linux" { send "\x01"; send "x" } timeout { exit 3 }
50+ expect "riscv32 GNU/Linux" { send "ip addr add 10.0.2.15/24 dev eth0\n" } timeout { exit 3 }
51+ expect "# " { send "ip link set eth0 up\n"}
52+ expect "# " { send "ip route add default via 10.0.2.2\n"}
53+ expect "# " { send "ping -c 3 10.0.2.2\n" }
54+ expect "3 packets transmitted, 3 packets received, 0% packet loss" { } timeout { exit 4 }
5255 }
5356DONE
5457}
Original file line number Diff line number Diff line change 66 path = mini-gdbstub
77 url = https://github.com/RinHizakura/mini-gdbstub
88 shallow = true
9+ [submodule "minislirp "]
10+ path = minislirp
11+ url = https://github.com/edubart/minislirp
12+ shallow = true
Original file line number Diff line number Diff line change @@ -51,6 +51,7 @@ $(call set-feature, VIRTIONET)
5151ifeq ($(call has, VIRTIONET) , 1)
5252 OBJS_EXTRA += virtio-net.o
5353 OBJS_EXTRA += netdev.o
54+ OBJS_EXTRA += slirp.o
5455endif
5556
5657# virtio-snd
@@ -113,6 +114,17 @@ $(GDBSTUB_LIB): mini-gdbstub/Makefile
113114 $(MAKE ) -C $(dir $< )
114115$(OBJS ) : $(GDBSTUB_LIB )
115116
117+ ifeq ($(call has, VIRTIONET) , 1)
118+ MINISLIRP_DIR := minislirp
119+ MINISLIRP_LIB := minislirp/src/libslirp.a
120+ LDFLAGS += $(MINISLIRP_LIB )
121+ $(MINISLIRP_DIR ) /src/Makefile :
122+ git submodule update --init $(MINISLIRP_DIR )
123+ $(MINISLIRP_LIB ) : $(MINISLIRP_DIR ) /src/Makefile
124+ $(MAKE ) -C $(dir $< )
125+ $(OBJS ) : $(MINISLIRP_LIB )
126+ endif
127+
116128$(BIN ) : $(OBJS )
117129 $(VECHO ) " LD\t$@ \n"
118130 $(Q )$(CC ) -o $@ $^ $(LDFLAGS )
@@ -171,6 +183,7 @@ build-image:
171183clean :
172184 $(Q )$(RM ) $(BIN ) $(OBJS ) $(deps )
173185 $(Q )$(MAKE ) -C mini-gdbstub clean
186+ $(Q )$(MAKE ) -C minislirp/src clean
174187
175188distclean : clean
176189 $(Q )$(RM ) riscv-harts.dtsi
Original file line number Diff line number Diff line change 11#pragma once
22
3+ #if SEMU_HAS (VIRTIONET )
34#include "netdev.h"
5+ #endif
46#include "riscv.h"
57#include "virtio.h"
68
@@ -120,6 +122,8 @@ void virtio_net_write(hart_t *core,
120122 uint32_t value );
121123void virtio_net_refresh_queue (virtio_net_state_t * vnet );
122124
125+ void virtio_net_recv_from_peer (void * peer );
126+
123127bool virtio_net_init (virtio_net_state_t * vnet , const char * name );
124128#endif /* SEMU_HAS(VIRTIONET) */
125129
Original file line number Diff line number Diff line change @@ -761,9 +761,38 @@ static int semu_run(emu_state_t *emu)
761761
762762 /* Emulate */
763763 while (!emu -> stopped ) {
764- ret = semu_step (emu );
765- if (ret )
766- return ret ;
764+ #if SEMU_HAS (VIRTIONET )
765+ int i = 0 ;
766+ if (emu -> vnet .peer .type == NETDEV_IMPL_user && boot_complete ) {
767+ net_user_options_t * usr = (net_user_options_t * ) emu -> vnet .peer .op ;
768+
769+ uint32_t timeout = -1 ;
770+ usr -> pfd_len = 1 ;
771+ slirp_pollfds_fill_socket (usr -> slirp , & timeout ,
772+ semu_slirp_add_poll_socket , usr );
773+
774+ /* Poll the internal pipe for incoming data. If data is
775+ * available (POLL_IN), process it and forward it to the
776+ * virtio-net device.
777+ */
778+ int pollout = poll (usr -> pfd , usr -> pfd_len , 1 );
779+ if (usr -> pfd [0 ].revents & POLLIN ) {
780+ virtio_net_recv_from_peer (usr -> peer );
781+ }
782+ slirp_pollfds_poll (usr -> slirp , (pollout <= 0 ),
783+ semu_slirp_get_revents , usr );
784+ for (i = 0 ; i < SLIRP_POLL_INTERVAL ; i ++ ) {
785+ ret = semu_step (emu );
786+ if (ret )
787+ return ret ;
788+ }
789+ } else
790+ #endif
791+ {
792+ ret = semu_step (emu );
793+ if (ret )
794+ return ret ;
795+ }
767796 }
768797
769798 /* unreachable */
Original file line number Diff line number Diff line change 88#include <string.h>
99#include <sys/ioctl.h>
1010
11+ #include "device.h"
1112#include "netdev.h"
1213
1314static int net_init_tap ();
@@ -55,9 +56,19 @@ static int net_init_tap(netdev_t *netdev)
5556 return 0 ;
5657}
5758
58- static int net_init_user (netdev_t * netdev UNUSED )
59+ static int net_init_user (netdev_t * netdev )
5960{
60- /* TODO: create slirp dev */
61+ net_user_options_t * usr = (net_user_options_t * ) netdev -> op ;
62+ memset (usr , 0 , sizeof (* usr ));
63+ usr -> peer = container_of (netdev , virtio_net_state_t , peer );
64+ if (pipe (usr -> channel ) < 0 )
65+ return false;
66+ assert (fcntl (usr -> channel [SLIRP_READ_SIDE ], F_SETFL ,
67+ fcntl (usr -> channel [SLIRP_READ_SIDE ], F_GETFL , 0 ) |
68+ O_NONBLOCK ) >= 0 );
69+
70+ net_slirp_init (usr );
71+
6172 return 0 ;
6273}
6374
Original file line number Diff line number Diff line change 11#pragma once
22
3- #include <stdbool.h>
3+ #include <poll.h>
4+ #include <unistd.h>
5+
6+ #include "minislirp/src/libslirp.h"
7+ #include "utils.h"
8+
49
510/* clang-format off */
611#define SUPPORTED_DEVICES \
@@ -18,10 +23,34 @@ typedef struct {
1823 int tap_fd ;
1924} net_tap_options_t ;
2025
26+ /* SLIRP */
27+ #define SLIRP_POLL_INTERVAL 100000
28+ #define SLIRP_READ_SIDE 0
29+ #define SLIRP_WRITE_SIDE 1
2130typedef struct {
22- /* TODO: Implement user option */
31+ semu_timer_t timer ;
32+ Slirp * slirp ;
33+ SlirpTimerId id ;
34+ void * cb_opaque ;
35+ void (* cb )(void * opaque );
36+ int64_t expire_timer_msec ;
37+ } slirp_timer ;
38+
39+ typedef struct {
40+ Slirp * slirp ;
41+ int channel [2 ];
42+ int pfd_len ;
43+ int pfd_size ;
44+ struct pollfd * pfd ;
45+ slirp_timer * timer ;
46+ void * peer ;
2347} net_user_options_t ;
2448
49+ Slirp * slirp_create (net_user_options_t * usr , SlirpConfig * cfg );
50+ int net_slirp_init (net_user_options_t * usr );
51+ int semu_slirp_add_poll_socket (slirp_os_socket fd , int events , void * opaque );
52+ int semu_slirp_get_revents (int idx , void * opaque );
53+
2554typedef struct {
2655 char * name ;
2756 netdev_impl_t type ;
You can’t perform that action at this time.
0 commit comments