Well I just found a nice surprise. Despite that email thread, it looks like
the helper program is actually in src/util/tap. That might at least shorten
the path to something that works.

Gabe

On Thu, Jun 1, 2017 at 2:05 PM, Gabe Black <[email protected]> wrote:

> Ok, thanks. I'll give that a try.
>
> Gabe
>
> On Thu, Jun 1, 2017 at 9:03 AM, Jason Lowe-Power <[email protected]>
> wrote:
>
>> 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
>
>
>
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to