File tree 10 files changed +347
-13
lines changed
10 files changed +347
-13
lines changed Original file line number Diff line number Diff line change @@ -45,10 +45,13 @@ ASSERT expect <<DONE
45
45
expect "riscv32 GNU/Linux" { send "ip l set eth0 up\n" } timeout { exit 3 }
46
46
expect "# " { send "ip a add 192.168.10.2/24 dev eth0\n" }
47
47
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 }
49
49
} 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 }
52
55
}
53
56
DONE
54
57
}
Original file line number Diff line number Diff line change 6
6
path = mini-gdbstub
7
7
url = https://github.com/RinHizakura/mini-gdbstub
8
8
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)
51
51
ifeq ($(call has, VIRTIONET) , 1)
52
52
OBJS_EXTRA += virtio-net.o
53
53
OBJS_EXTRA += netdev.o
54
+ OBJS_EXTRA += slirp.o
54
55
endif
55
56
56
57
# virtio-snd
@@ -113,6 +114,17 @@ $(GDBSTUB_LIB): mini-gdbstub/Makefile
113
114
$(MAKE ) -C $(dir $< )
114
115
$(OBJS ) : $(GDBSTUB_LIB )
115
116
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
+
116
128
$(BIN ) : $(OBJS )
117
129
$(VECHO ) " LD\t$@ \n"
118
130
$(Q )$(CC ) -o $@ $^ $(LDFLAGS )
@@ -171,6 +183,7 @@ build-image:
171
183
clean :
172
184
$(Q )$(RM ) $(BIN ) $(OBJS ) $(deps )
173
185
$(Q )$(MAKE ) -C mini-gdbstub clean
186
+ $(Q )$(MAKE ) -C minislirp/src clean
174
187
175
188
distclean : clean
176
189
$(Q )$(RM ) riscv-harts.dtsi
Original file line number Diff line number Diff line change 1
1
#pragma once
2
2
3
+ #if SEMU_HAS (VIRTIONET )
3
4
#include "netdev.h"
5
+ #endif
4
6
#include "riscv.h"
5
7
#include "virtio.h"
6
8
@@ -120,6 +122,8 @@ void virtio_net_write(hart_t *core,
120
122
uint32_t value );
121
123
void virtio_net_refresh_queue (virtio_net_state_t * vnet );
122
124
125
+ void virtio_net_recv_from_peer (void * peer );
126
+
123
127
bool virtio_net_init (virtio_net_state_t * vnet , const char * name );
124
128
#endif /* SEMU_HAS(VIRTIONET) */
125
129
Original file line number Diff line number Diff line change @@ -761,9 +761,38 @@ static int semu_run(emu_state_t *emu)
761
761
762
762
/* Emulate */
763
763
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
+ }
767
796
}
768
797
769
798
/* unreachable */
Original file line number Diff line number Diff line change 8
8
#include <string.h>
9
9
#include <sys/ioctl.h>
10
10
11
+ #include "device.h"
11
12
#include "netdev.h"
12
13
13
14
static int net_init_tap ();
@@ -55,9 +56,19 @@ static int net_init_tap(netdev_t *netdev)
55
56
return 0 ;
56
57
}
57
58
58
- static int net_init_user (netdev_t * netdev UNUSED )
59
+ static int net_init_user (netdev_t * netdev )
59
60
{
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
+
61
72
return 0 ;
62
73
}
63
74
Original file line number Diff line number Diff line change 1
1
#pragma once
2
2
3
- #include <stdbool.h>
3
+ #include <poll.h>
4
+ #include <unistd.h>
5
+
6
+ #include "minislirp/src/libslirp.h"
7
+ #include "utils.h"
8
+
4
9
5
10
/* clang-format off */
6
11
#define SUPPORTED_DEVICES \
@@ -18,10 +23,34 @@ typedef struct {
18
23
int tap_fd ;
19
24
} net_tap_options_t ;
20
25
26
+ /* SLIRP */
27
+ #define SLIRP_POLL_INTERVAL 100000
28
+ #define SLIRP_READ_SIDE 0
29
+ #define SLIRP_WRITE_SIDE 1
21
30
typedef 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 ;
23
47
} net_user_options_t ;
24
48
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
+
25
54
typedef struct {
26
55
char * name ;
27
56
netdev_impl_t type ;
You can’t perform that action at this time.
0 commit comments