Hah, nice.  I'm glad you found it.  The separation was mostly due to
permissions stuff I'm sure.  Looking at the example program, I implemented
both pcap and ethernet support where ethernet was done using bpf and
libdnet.  (Those are also dependencies that we don't need).  I didn't
actually do it with a tap device.  I recall that it worked with one
caveat.  Some times, the simulated clock would go so fast (because the
system was idle) that various timeouts on the simulated host would fire.  I
remember thinking that I needed to add a throttle that would prevent the
eventq from ticking more than one millisecond per millisecond.

As for the protocol to make it work with socat.  The issue is that I used
TCP.  I'm not sure why, but because ethernet frames don't come with a
length and TCP is stream oriented, I needed to add the datagram size.  I'm
guessing that I just followed the pcap format so that I could suck in pcap
files directly to replay them.  If you want to use socat, then I'd use a
unix domain socket in a datagram mode (without the header) and I bet that
will work with the tap device on socat properly.

Of course, using tap directly is pretty easy too, but again, you have the
permissions problem to work around and that seemed too cumbersome for me.

The benefit of tap over pcap is that tap will work as if you had an
ethernet connection directly to the machine.  You could bridge it to the
real ethernet or nat to the real world.  With bpf/dnet, you're connecting
to the physical ethernet adapter only which may or may not be what you
want.  I can't remember if the host would see traffic in that case or not.

  Nate

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

> 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
>
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to