Yeah, I think if you use tunctl with -u and -g options, then you can Linux
it's ok to give a tun device to that specific regular user. I haven't tried
it, but I think if I ran:

sudo tunctl -u gabeblack -g gabeblack -t gem5-tap

and then ran gem5 as myself and tried to access that device, it would
actually let me.

As far as the throttling, I actually implemented that already a while ago
for I think unrelated reasons (interacting with the system maybe?), so that
shouldn't be an issue. It's a property on the simulation root and can be
turned on in fs.py with the --timesync option. The default syncing
frequency is once every 100ms (which suggests human time frame), but it's
adjustable.

I do have m5tap working right now (patches coming soon), but I think using
tap may be easier to get working more generally, and (assuming the tunctl
thing works) should do most of the things I expect people will want to do
in a fairly clean way. At least if that way blows up spectacularly m5tap
will still be there.

Gabe

On Thu, Jun 1, 2017 at 4:24 PM, nathan binkert <[email protected]> wrote:

> The note about dependencies was that as a separate program, I didn't need
> to change the gem5 dependencies.  Also, you could just use UDP instead of
> unix domain.  That should work fine with socat as well (without the
> header).
>
>   Nate
>
> On Thu, Jun 1, 2017 at 4:21 PM, nathan binkert <[email protected]> wrote:
>
> > 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
>
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to