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