Hi Gabe,
I also did some work trying to revive ethertap recently. I think it would
be *really cool* to get gem5 to be able to easily talk to the outside
world. I think that it is worth it for this to only work on one platform.
If someone else comes along and wants to extend it to other, they can do
that then.
Overall, I came to similar conclusions as you did. Piping everything
through socat is at least mildly broken, and it makes more sense go
straight through the tap/tun device.
My initial thought was to copy the way qemu sets up a network bridge. But I
never really dug into it enough to fully understand how the qemu code works.
Below are the notes that I took while I was trying to get it to work
(mostly just a knowledge dump so you may or may not be able to get anything
new out of it). The code I have is based on the old mercurial repo, so it
will take me a little time to clean it up so it applies cleanly and works
with the current mainline. I'll try to do that this weekend.
I ended up getting it mostly working, except for the socat issues that you
have run into. If I ran socat in a while loop (shown below) the
gem5->internet connection would eventually get all of the data since the
socat link re-established itself.
Cheers,
Jason
Getting networking going
========================
To do
-----
Figure out why it works with fs.py but not with my config files. Ugh!
Disk changes
------------
To get things to work in ubuntu, you have to add the device to
/etc/network/interfaces.
To find the device name, run ifconfig -a
.. code-block:: sh
ifconfig -a
.. code-block::
enp0s0 Link encap:Ethernet HWaddr 00:90:00:00:00:01
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:3420 (3.4 KB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:1760 errors:0 dropped:0 overruns:0 frame:0
TX packets:1760 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:130240 (130.2 KB) TX bytes:130240 (130.2 KB)
Mine was "enp0s0".
Update /etc/network/interfaces with the right device name:
.. code-block::
auto enp0s0
iface enp0s0 inet dhcp
On the host to enable a bridge
------------------------------
Create a bridge. This is the script I used.
Saved the script as qemu-ifup, and I ran "sudo ./qemu-ifup".
.. code-block:: sh
#!/bin/sh
#
# Copyright IBM, Corp. 2010
#
# Authors:
# Anthony Liguori <[email protected]>
#
# This work is licensed under the terms of the GNU GPL, version 2. See
# the COPYING file in the top-level directory.
# Set to the name of your bridge
BRIDGE=br0
# Network information
NETWORK=192.168.53.0
NETMASK=255.255.255.0
GATEWAY=192.168.53.1
DHCPRANGE=192.168.53.2,192.168.53.254
# Optionally parameters to enable PXE support
TFTPROOT=
BOOTP=
do_brctl() {
brctl "$@"
}
do_ifconfig() {
ifconfig "$@"
}
do_dd() {
dd "$@"
}
do_iptables_restore() {
iptables-restore "$@"
}
do_dnsmasq() {
dnsmasq "$@"
}
check_bridge() {
if do_brctl show | grep "^$1" > /dev/null 2> /dev/null; then
return 1
else
return 0
fi
}
create_bridge() {
do_brctl addbr "$1"
do_brctl stp "$1" off
do_brctl setfd "$1" 0
do_ifconfig "$1" "$GATEWAY" netmask "$NETMASK" up
}
enable_ip_forward() {
echo 1 | do_dd of=/proc/sys/net/ipv4/ip_forward > /dev/null
}
add_filter_rules() {
do_iptables_restore <<EOF
# Generated by iptables-save v1.3.6 on Fri Aug 24 15:20:25 2007
*nat
:PREROUTING ACCEPT [61:9671]
:POSTROUTING ACCEPT [121:7499]
:OUTPUT ACCEPT [132:8691]
-A POSTROUTING -s $NETWORK/$NETMASK -j MASQUERADE
COMMIT
# Completed on Fri Aug 24 15:20:25 2007
# Generated by iptables-save v1.3.6 on Fri Aug 24 15:20:25 2007
*filter
:INPUT ACCEPT [1453:976046]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1605:194911]
-A INPUT -i $BRIDGE -p tcp -m tcp --dport 67 -j ACCEPT
-A INPUT -i $BRIDGE -p udp -m udp --dport 67 -j ACCEPT
-A INPUT -i $BRIDGE -p tcp -m tcp --dport 53 -j ACCEPT
-A INPUT -i $BRIDGE -p udp -m udp --dport 53 -j ACCEPT
-A FORWARD -i $1 -o $1 -j ACCEPT
-A FORWARD -s $NETWORK/$NETMASK -i $BRIDGE -j ACCEPT
-A FORWARD -d $NETWORK/$NETMASK -o $BRIDGE -m state --state
RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o $BRIDGE -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -i $BRIDGE -j REJECT --reject-with icmp-port-unreachable
COMMIT
# Completed on Fri Aug 24 15:20:25 2007
EOF
}
start_dnsmasq() {
do_dnsmasq \
--strict-order \
--except-interface=lo \
--interface=$BRIDGE \
--listen-address=$GATEWAY \
--bind-interfaces \
--dhcp-range=$DHCPRANGE \
--conf-file="" \
--pid-file=/var/run/qemu-dnsmasq-$BRIDGE.pid \
--dhcp-leasefile=/var/run/qemu-dnsmasq-$BRIDGE.leases \
--dhcp-no-override \
${TFTPROOT:+"--enable-tftp"} \
${TFTPROOT:+"--tftp-root=$TFTPROOT"} \
${BOOTP:+"--dhcp-boot=$BOOTP"}
}
setup_bridge_nat() {
if check_bridge "$1" ; then
create_bridge "$1"
enable_ip_forward
add_filter_rules "$1"
start_dnsmasq "$1"
fi
}
setup_bridge_vlan() {
if check_bridge "$1" ; then
create_bridge "$1"
start_dnsmasq "$1"
fi
}
setup_bridge_nat "$BRIDGE"
if test "$1" ; then
do_ifconfig "$1" 0.0.0.0 up
do_brctl addif "$BRIDGE" "$1"
fi
After starting gem5, I ran the following socat command to create a tap
device and
connect it to the bridge.
.. code-block:: sh
while :; do
socat -s TCP:localhost:3500,forever TUN:
192.168.53.1/24,up,tun-type=tap,user=powerjg &
brctl addif br0 tap1;
fg;
done;
It's wrapped in a while loop because there are lots of errors and it needs
to be
restarted every time there is an error.
You may want to use -d -d -d as the option to socat to output more
information.
Also, I want to modify this so that it waits for the socket to be connected.
I think that's possible.
On Wed, May 31, 2017 at 10:57 PM Gabe Black <[email protected]> wrote:
> One other possible use for the bridge might be to adapt a non-ethernet
> network in gem5 to the ethernet network tap expects? I suppose it could do
> other forms of translation too, as necessary.
>
> Gabe
>
> On Wed, May 31, 2017 at 8:44 PM, Gabe Black <[email protected]> wrote:
>
> > Hello folks, I think specifically Nate. I have a need to get EtherTap
> > working again, and after a lot of digging around and looking at this
> > conversation from 5 years ago:
> >
> > http://thread.gmane.org/gmane.comp.emulators.m5.devel/14675
> >
> > I've made some progress understanding how to do that. I think one of the
> > big remaining questions I have is why there was an extra program which
> > opened the tap device and sent the packets to gem5 over a TCP socket
> > instead of gem5 just opening the tap device itself and doing the reading
> on
> > its own. That would certainly be simpler, at least as far as I can tell
> > with admittedly not a great deal of expertise to work with.
> >
> > There are a couple potential reasons I could think of. First, it could
> > have been a permissions thing. It looks like you need special magical
> > permissions to create a tap device, and it sounded from that (and this
> > http://gem5.org/Nate%27s_Wish_List) that folks understandably didn't
> want
> > to have to run all of gem5 as root just to get that part to work. Doing a
> > bit more research, it looks like you can use tunctl to create a
> persistent
> > tap device and give it to a particular user. Then that use can open and
> use
> > the device without having to be root. root would still need to configure
> > the device, but that would seem to mitigate that issue.
> >
> > The other reason could be that the ioctls, etc., needed to create and
> > interact with tap devices varies between OSes, and folks didn't want to
> tie
> > the implementation to any particular OSes scheme. In that case, the
> little
> > bridge program could do the right dance for the OS in use, and then
> > communicate to generic gem5 over the TCP socket. It could even be that a
> > tap style interface doesn't even exist on a particular OS, and so the
> > bridge has to do some other fancy trick to get and receive ethernet
> frames
> > from the OS.
> >
> > This seems like a harder problem to address, although is there really a
> > big group of people out there that would use ethernet bridging on a
> > non-Linux OS? Maybe? It would be nice to exclude people by design, if
> > possible.
> >
> > In the email thread I linked to above, the author said they were using
> > socat to connect between the tap device and gem5. I'd never heard of
> socat
> > before and this almost works, except that gem5 expects the size of the
> data
> > to appear at the start of the data it gets over port 3500. Since socat
> > doesn't do that, gem5 thinks the data size is something ridiculous and
> ends
> > up waiting to accumulate enough data before sending the incoming frame
> into
> > the network. Similarly, it puts the size at the start of the data its
> > sending, and I think that confuses socat. Surprisingly I think some DHCP
> > discover packets make it onto the network, but sometimes socat gets upset
> > and dies because of an "Invalid argument". I think socat just isn't the
> > right tool for this job, especially considering how it explodes when
> > certain admittedly incorrect things are sent its way it's not expecting.
> >
> >
> > Anyway, I can forge ahead doing whatever seems best to me, but I figured
> > I'd ask for suggestions in case anybody really wanted things done one way
> > or another for some reason. Let me know!
> >
> > Gabe
> >
> _______________________________________________
> gem5-dev mailing list
> [email protected]
> http://m5sim.org/mailman/listinfo/gem5-dev
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev