Update and rename MantenerFIFO to MantenerFIFO.md
[vsorcdistro/.git] / mininet / util / install.sh
1 #!/usr/bin/env bash
2
3 # Mininet install script for Ubuntu (and Debian Wheezy+)
4 # Brandon Heller (brandonh@stanford.edu)
5
6 # Fail on error
7 set -e
8
9 # Fail on unset var usage
10 set -o nounset
11
12 # Get directory containing mininet folder
13 MININET_DIR="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd -P )"
14
15 # Set up build directory, which by default is the working directory
16 #  unless the working directory is a subdirectory of mininet,
17 #  in which case we use the directory containing mininet
18 BUILD_DIR="$(pwd -P)"
19 case $BUILD_DIR in
20   $MININET_DIR/*) BUILD_DIR=$MININET_DIR;; # currect directory is a subdirectory
21   *) BUILD_DIR=$BUILD_DIR;;
22 esac
23
24 # Location of CONFIG_NET_NS-enabled kernel(s)
25 KERNEL_LOC=http://www.openflow.org/downloads/mininet
26
27 # Attempt to identify Linux release
28
29 DIST=Unknown
30 RELEASE=Unknown
31 CODENAME=Unknown
32 ARCH=`uname -m`
33 if [ "$ARCH" = "x86_64" ]; then ARCH="amd64"; fi
34 if [ "$ARCH" = "i686" ]; then ARCH="i386"; fi
35
36 test -e /etc/debian_version && DIST="Debian"
37 grep Ubuntu /etc/lsb-release &> /dev/null && DIST="Ubuntu"
38 if [ "$DIST" = "Ubuntu" ] || [ "$DIST" = "Debian" ]; then
39     # Truly non-interactive apt-get installation
40     install='sudo DEBIAN_FRONTEND=noninteractive apt-get -y -q install'
41     remove='sudo DEBIAN_FRONTEND=noninteractive apt-get -y -q remove'
42     pkginst='sudo dpkg -i'
43     update='sudo apt-get'
44     # Prereqs for this script
45     if ! which lsb_release &> /dev/null; then
46         $install lsb-release
47     fi
48 fi
49 test -e /etc/fedora-release && DIST="Fedora"
50 test -e /etc/redhat-release && DIST="RedHatEnterpriseServer"
51 if [ "$DIST" = "Fedora" -o "$DIST" = "RedHatEnterpriseServer" ]; then
52     install='sudo yum -y install'
53     remove='sudo yum -y erase'
54     pkginst='sudo rpm -ivh'
55     update='sudo yum'
56     # Prereqs for this script
57     if ! which lsb_release &> /dev/null; then
58         $install redhat-lsb-core
59     fi
60 fi
61 test -e /etc/SuSE-release && DIST="SUSE Linux"
62 if [ "$DIST" = "SUSE Linux" ]; then
63     install='sudo zypper --non-interactive install '
64     remove='sudo zypper --non-interactive  remove '
65     pkginst='sudo rpm -ivh'
66     # Prereqs for this script
67     if ! which lsb_release &> /dev/null; then
68                 $install openSUSE-release
69     fi
70 fi
71 if which lsb_release &> /dev/null; then
72     DIST=`lsb_release -is`
73     RELEASE=`lsb_release -rs`
74     CODENAME=`lsb_release -cs`
75 fi
76 echo "Detected Linux distribution: $DIST $RELEASE $CODENAME $ARCH"
77
78 # Kernel params
79
80 KERNEL_NAME=`uname -r`
81 KERNEL_HEADERS=kernel-headers-${KERNEL_NAME}
82
83 # Treat Raspbian as Debian
84 [ "$DIST" = 'Raspbian' ] && DIST='Debian'
85
86 DISTS='Ubuntu|Debian|Fedora|RedHatEnterpriseServer|SUSE LINUX'
87 if ! echo $DIST | egrep "$DISTS" >/dev/null; then
88     echo "Install.sh currently only supports $DISTS."
89     exit 1
90 fi
91
92 # More distribution info
93 DIST_LC=`echo $DIST | tr [A-Z] [a-z]` # as lower case
94
95
96 # Determine whether version $1 >= version $2
97 # usage: if version_ge 1.20 1.2.3; then echo "true!"; fi
98 function version_ge {
99     # sort -V sorts by *version number*
100     latest=`printf "$1\n$2" | sort -V | tail -1`
101     # If $1 is latest version, then $1 >= $2
102     [ "$1" == "$latest" ]
103 }
104
105 # Attempt to identify Python version
106 PYTHON=${PYTHON:-python}
107 if $PYTHON --version |& grep 'Python 2' > /dev/null; then
108     PYTHON_VERSION=2; PYPKG=python
109 else
110     PYTHON_VERSION=3; PYPKG=python3
111 fi
112 echo "${PYTHON} is version ${PYTHON_VERSION}"
113
114 # Kernel Deb pkg to be removed:
115 KERNEL_IMAGE_OLD=linux-image-2.6.26-33-generic
116
117 DRIVERS_DIR=/lib/modules/${KERNEL_NAME}/kernel/drivers/net
118
119 OVS_RELEASE=1.4.0
120 OVS_PACKAGE_LOC=https://github.com/downloads/mininet/mininet
121 OVS_BUILDSUFFIX=-ignore # was -2
122 OVS_PACKAGE_NAME=ovs-$OVS_RELEASE-core-$DIST_LC-$RELEASE-$ARCH$OVS_BUILDSUFFIX.tar
123 OVS_TAG=v$OVS_RELEASE
124
125 OF13_SWITCH_REV=${OF13_SWITCH_REV:-""}
126
127
128 function kernel {
129     echo "Install Mininet-compatible kernel if necessary"
130     $update update
131     if ! $install linux-image-$KERNEL_NAME; then
132         echo "Could not install linux-image-$KERNEL_NAME"
133         echo "Skipping - assuming installed kernel is OK."
134     fi
135 }
136
137 function kernel_clean {
138     echo "Cleaning kernel..."
139
140     # To save disk space, remove previous kernel
141     if ! $remove $KERNEL_IMAGE_OLD; then
142         echo $KERNEL_IMAGE_OLD not installed.
143     fi
144
145     # Also remove downloaded packages:
146     rm -f $HOME/linux-headers-* $HOME/linux-image-*
147 }
148
149 # Install Mininet deps
150 function mn_deps {
151     echo "Installing Mininet dependencies"
152     if [ "$DIST" = "Fedora" -o "$DIST" = "RedHatEnterpriseServer" ]; then
153         $install gcc make socat psmisc xterm openssh-clients iperf \
154             iproute telnet python-setuptools libcgroup-tools \
155             ethtool help2man pyflakes pylint python-pep8 python-pexpect
156     elif [ "$DIST" = "SUSE LINUX"  ]; then
157                 $install gcc make socat psmisc xterm openssh iperf \
158                         iproute telnet ${PYPKG}-setuptools libcgroup-tools \
159                         ethtool help2man python-pyflakes python3-pylint \
160                         python-pep8 ${PYPKG}-pexpect ${PYPKG}-tk
161     else  # Debian/Ubuntu
162         $install gcc make socat psmisc xterm ssh iperf telnet \
163                  cgroup-bin ethtool help2man pyflakes pylint pep8 \
164                  ${PYPKG}-setuptools ${PYPKG}-pexpect ${PYPKG}-tk
165         $install iproute2 || $install iproute
166     fi
167
168     echo "Installing Mininet core"
169     pushd $MININET_DIR/mininet
170     sudo PYTHON=${PYTHON} make install
171     popd
172 }
173
174 # Install Mininet developer dependencies
175 function mn_dev {
176     echo "Installing Mininet developer dependencies"
177     $install doxygen doxypy texlive-fonts-recommended
178     if ! $install doxygen-latex; then
179         echo "doxygen-latex not needed"
180     fi
181 }
182
183 # The following will cause a full OF install, covering:
184 # -user switch
185 # The instructions below are an abbreviated version from
186 # http://www.openflowswitch.org/wk/index.php/Debian_Install
187 function of {
188     echo "Installing OpenFlow reference implementation..."
189     cd $BUILD_DIR
190     $install autoconf automake libtool make gcc
191     if [ "$DIST" = "Fedora" -o "$DIST" = "RedHatEnterpriseServer" ]; then
192         $install git pkgconfig glibc-devel
193         elif [ "$DIST" = "SUSE LINUX"  ]; then
194        $install git pkgconfig glibc-devel
195     else
196         $install git-core autotools-dev pkg-config libc6-dev
197     fi
198     # was: git clone git://openflowswitch.org/openflow.git
199     # Use our own fork on github for now:
200     git clone git://github.com/mininet/openflow
201     cd $BUILD_DIR/openflow
202
203     # Patch controller to handle more than 16 switches
204     patch -p1 < $MININET_DIR/mininet/util/openflow-patches/controller.patch
205
206     # Resume the install:
207     ./boot.sh
208     ./configure
209     make
210     sudo make install
211     cd $BUILD_DIR
212 }
213
214 function of13 {
215     echo "Installing OpenFlow 1.3 soft switch implementation..."
216     cd $BUILD_DIR/
217     $install git-core autoconf automake autotools-dev pkg-config \
218         make gcc g++ libtool libc6-dev cmake libpcap-dev  \
219         unzip libpcre3-dev flex bison libboost-dev
220     if [ "$DIST" = "Ubuntu" ] && version_le $RELEASE 16.04; then
221         $install libxerces-c2-dev
222     else
223         $install libxerces-c-dev
224     fi
225     if [ ! -d "ofsoftswitch13" ]; then
226         git clone https://github.com/CPqD/ofsoftswitch13.git
227         if [[ -n "$OF13_SWITCH_REV" ]]; then
228             cd ofsoftswitch13
229             git checkout ${OF13_SWITCH_REV}
230             cd ..
231         fi
232     fi
233
234     # Install netbee
235     if [ ! -d "netbee" ]; then
236         git clone https://github.com/netgroup-polito/netbee.git
237     fi
238     cd netbee/src
239     cmake .
240     make
241
242     cd $BUILD_DIR
243     sudo cp netbee/bin/libn*.so /usr/local/lib
244     sudo ldconfig
245     sudo cp -R netbee/include/ /usr/
246
247     # Resume the install:
248     cd $BUILD_DIR/ofsoftswitch13
249     ./boot.sh
250     ./configure
251     make
252     sudo make install
253     cd $BUILD_DIR
254 }
255
256
257 function install_wireshark {
258     if ! which wireshark; then
259         echo "Installing Wireshark"
260         if [ "$DIST" = "Fedora" -o "$DIST" = "RedHatEnterpriseServer" ]; then
261             $install wireshark wireshark-gnome
262                 elif [ "$DIST" = "SUSE LINUX"  ]; then
263                         $install wireshark
264         else
265             $install wireshark tshark
266         fi
267     fi
268
269     # Copy coloring rules: OF is white-on-blue:
270     echo "Optionally installing wireshark color filters"
271     mkdir -p $HOME/.wireshark
272     cp -n $MININET_DIR/mininet/util/colorfilters $HOME/.wireshark
273
274     echo "Checking Wireshark version"
275     WSVER=`wireshark -v | egrep -o '[0-9\.]+' | head -1`
276     if version_ge $WSVER 1.12; then
277         echo "Wireshark version $WSVER >= 1.12 - returning"
278         return
279     fi
280
281     echo "Cloning LoxiGen and building openflow.lua dissector"
282     cd $BUILD_DIR
283     git clone https://github.com/floodlight/loxigen.git
284     cd loxigen
285     make wireshark
286
287     # Copy into plugin directory
288     # libwireshark0/ on 11.04; libwireshark1/ on later
289     WSDIR=`find /usr/lib -type d -name 'libwireshark*' | head -1`
290     WSPLUGDIR=$WSDIR/plugins/
291     PLUGIN=loxi_output/wireshark/openflow.lua
292     sudo cp $PLUGIN $WSPLUGDIR
293     echo "Copied openflow plugin $PLUGIN to $WSPLUGDIR"
294
295     cd $BUILD_DIR
296 }
297
298
299 # Install Open vSwitch specific version Ubuntu package
300 function ubuntuOvs {
301     echo "Creating and Installing Open vSwitch packages..."
302
303     OVS_SRC=$BUILD_DIR/openvswitch
304     OVS_TARBALL_LOC=http://openvswitch.org/releases
305
306     if ! echo "$DIST" | egrep "Ubuntu|Debian" > /dev/null; then
307         echo "OS must be Ubuntu or Debian"
308         $cd BUILD_DIR
309         return
310     fi
311     if [ "$DIST" = "Ubuntu" ] && ! version_ge $RELEASE 12.04; then
312         echo "Ubuntu version must be >= 12.04"
313         cd $BUILD_DIR
314         return
315     fi
316     if [ "$DIST" = "Debian" ] && ! version_ge $RELEASE 7.0; then
317         echo "Debian version must be >= 7.0"
318         cd $BUILD_DIR
319         return
320     fi
321
322     rm -rf $OVS_SRC
323     mkdir -p $OVS_SRC
324     cd $OVS_SRC
325
326     if wget $OVS_TARBALL_LOC/openvswitch-$OVS_RELEASE.tar.gz 2> /dev/null; then
327         tar xzf openvswitch-$OVS_RELEASE.tar.gz
328     else
329         echo "Failed to find OVS at $OVS_TARBALL_LOC/openvswitch-$OVS_RELEASE.tar.gz"
330         cd $BUILD_DIR
331         return
332     fi
333
334     # Remove any old packages
335
336     $remove openvswitch-common openvswitch-datapath-dkms openvswitch-pki openvswitch-switch \
337             openvswitch-controller || true
338
339     # Get build deps
340     $install build-essential fakeroot debhelper autoconf automake libssl-dev \
341              pkg-config bzip2 openssl python-all procps python-qt4 \
342              python-zopeinterface python-twisted-conch dkms dh-python dh-autoreconf \
343              uuid-runtime
344
345     # Build OVS
346     parallel=`grep processor /proc/cpuinfo | wc -l`
347     cd $BUILD_DIR/openvswitch/openvswitch-$OVS_RELEASE
348             DEB_BUILD_OPTIONS='parallel=$parallel nocheck' fakeroot debian/rules binary
349     cd ..
350     for pkg in common datapath-dkms pki switch; do
351         pkg=openvswitch-${pkg}_$OVS_RELEASE*.deb
352         echo "Installing $pkg"
353         $pkginst $pkg
354     done
355     if $pkginst openvswitch-controller_$OVS_RELEASE*.deb 2>/dev/null; then
356         echo "Ignoring error installing openvswitch-controller"
357     fi
358
359     /sbin/modinfo openvswitch
360     sudo ovs-vsctl show
361     # Switch can run on its own, but
362     # Mininet should control the controller
363     # This appears to only be an issue on Ubuntu/Debian
364     if sudo service openvswitch-controller stop 2>/dev/null; then
365         echo "Stopped running controller"
366     fi
367     if [ -e /etc/init.d/openvswitch-controller ]; then
368         sudo update-rc.d openvswitch-controller disable
369     fi
370 }
371
372
373 # Install Open vSwitch
374
375 function ovs {
376     echo "Installing Open vSwitch..."
377
378     if [ "$DIST" = "Fedora" -o "$DIST" = "RedHatEnterpriseServer" ]; then
379         $install openvswitch openvswitch-controller
380         return
381     fi
382
383     if [ "$DIST" = "Ubuntu" ] && ! version_ge $RELEASE 14.04; then
384         # Older Ubuntu versions need openvswitch-datapath/-dkms
385         # Manually installing openvswitch-datapath may be necessary
386         # for manually built kernel .debs using Debian's defective kernel
387         # packaging, which doesn't yield usable headers.
388         if ! dpkg --get-selections | grep openvswitch-datapath; then
389             # If you've already installed a datapath, assume you
390             # know what you're doing and don't need dkms datapath.
391             # Otherwise, install it.
392             $install openvswitch-datapath-dkms
393         fi
394     fi
395
396     $install openvswitch-switch
397     OVSC=""
398     if $install openvswitch-controller; then
399         OVSC="openvswitch-controller"
400     else
401         echo "Attempting to install openvswitch-testcontroller"
402         if $install openvswitch-testcontroller; then
403             OVSC="openvswitch-testcontroller"
404         else
405             echo "Failed - skipping openvswitch-testcontroller"
406         fi
407     fi
408     if [ "$OVSC" ]; then
409         # Switch can run on its own, but
410         # Mininet should control the controller
411         # This appears to only be an issue on Ubuntu/Debian
412         if sudo service $OVSC stop 2>/dev/null; then
413             echo "Stopped running controller"
414         fi
415         if [ -e /etc/init.d/$OVSC ]; then
416             sudo update-rc.d $OVSC disable
417         fi
418     fi
419 }
420
421 function remove_ovs {
422     pkgs=`dpkg --get-selections | grep openvswitch | awk '{ print $1;}'`
423     echo "Removing existing Open vSwitch packages:"
424     echo $pkgs
425     if ! $remove $pkgs; then
426         echo "Not all packages removed correctly"
427     fi
428     # For some reason this doesn't happen
429     if scripts=`ls /etc/init.d/*openvswitch* 2>/dev/null`; then
430         echo $scripts
431         for s in $scripts; do
432             s=$(basename $s)
433             echo SCRIPT $s
434             sudo service $s stop
435             sudo rm -f /etc/init.d/$s
436             sudo update-rc.d -f $s remove
437         done
438     fi
439     echo "Done removing OVS"
440 }
441
442 function ivs {
443     echo "Installing Indigo Virtual Switch..."
444
445     IVS_SRC=$BUILD_DIR/ivs
446
447     # Install dependencies
448     $install gcc make
449     if [ "$DIST" = "Fedora" -o "$DIST" = "RedHatEnterpriseServer" ]; then
450         $install git pkgconfig libnl3-devel libcap-devel openssl-devel
451     else
452         $install git-core pkg-config libnl-3-dev libnl-route-3-dev \
453             libnl-genl-3-dev
454     fi
455
456     # Install IVS from source
457     cd $BUILD_DIR
458     git clone git://github.com/floodlight/ivs $IVS_SRC
459     cd $IVS_SRC
460     git submodule update --init
461     make
462     sudo make install
463 }
464
465 # Install RYU
466 function ryu {
467     echo "Installing RYU..."
468
469     # install Ryu dependencies"
470     $install autoconf automake g++ libtool python make
471     if [ "$DIST" = "Ubuntu" -o "$DIST" = "Debian" ]; then
472         $install gcc python-pip python-dev libffi-dev libssl-dev \
473             libxml2-dev libxslt1-dev zlib1g-dev
474     fi
475
476     # fetch RYU
477     cd $BUILD_DIR/
478     git clone git://github.com/osrg/ryu.git ryu
479     cd ryu
480
481     # install ryu
482     sudo pip install -r tools/pip-requires -r tools/optional-requires \
483         -r tools/test-requires
484     sudo python setup.py install
485
486     # Add symbolic link to /usr/bin
487     sudo ln -s ./bin/ryu-manager /usr/local/bin/ryu-manager
488 }
489
490 # Install NOX with tutorial files
491 function nox {
492     echo "Installing NOX w/tutorial files..."
493
494     # Install NOX deps:
495     $install autoconf automake g++ libtool python python-twisted \
496                 swig libssl-dev make
497     if [ "$DIST" = "Debian" ]; then
498         $install libboost1.35-dev
499     elif [ "$DIST" = "Ubuntu" ]; then
500         $install python-dev libboost-dev
501         $install libboost-filesystem-dev
502         $install libboost-test-dev
503     fi
504     # Install NOX optional deps:
505     $install libsqlite3-dev python-simplejson
506
507     # Fetch NOX destiny
508     cd $BUILD_DIR/
509     git clone https://github.com/noxrepo/nox-classic.git noxcore
510     cd noxcore
511     if ! git checkout -b destiny remotes/origin/destiny ; then
512         echo "Did not check out a new destiny branch - assuming current branch is destiny"
513     fi
514
515     # Apply patches
516     git checkout -b tutorial-destiny
517     git am $MININET_DIR/mininet/util/nox-patches/*tutorial-port-nox-destiny*.patch
518     if [ "$DIST" = "Ubuntu" ] && version_ge $RELEASE 12.04; then
519         git am $MININET_DIR/mininet/util/nox-patches/*nox-ubuntu12-hacks.patch
520     fi
521
522     # Build
523     ./boot.sh
524     mkdir build
525     cd build
526     ../configure
527     make -j3
528     #make check
529
530     # Add NOX_CORE_DIR env var:
531     sed -i -e 's|# for examples$|&\nexport NOX_CORE_DIR=$BUILD_DIR/noxcore/build/src|' ~/.bashrc
532
533     # To verify this install:
534     #cd ~/noxcore/build/src
535     #./nox_core -v -i ptcp:
536 }
537
538 # Install NOX Classic/Zaku for OpenFlow 1.3
539 function nox13 {
540     echo "Installing NOX w/tutorial files..."
541
542     # Install NOX deps:
543     $install autoconf automake g++ libtool python python-twisted \
544         swig libssl-dev make
545     if [ "$DIST" = "Debian" ]; then
546         $install libboost1.35-dev
547     elif [ "$DIST" = "Ubuntu" ]; then
548         $install python-dev libboost-dev
549         $install libboost-filesystem-dev
550         $install libboost-test-dev
551     fi
552
553     # Fetch NOX destiny
554     cd $BUILD_DIR/
555     git clone https://github.com/CPqD/nox13oflib.git
556     cd nox13oflib
557
558     # Build
559     ./boot.sh
560     mkdir build
561     cd build
562     ../configure
563     make -j3
564     #make check
565
566     # To verify this install:
567     #cd ~/nox13oflib/build/src
568     #./nox_core -v -i ptcp:
569 }
570
571
572 # "Install" POX
573 function pox {
574     echo "Installing POX into $BUILD_DIR/pox..."
575     cd $BUILD_DIR
576     git clone https://github.com/noxrepo/pox.git
577 }
578
579 # Install OFtest
580 function oftest {
581     echo "Installing oftest..."
582
583     # Install deps:
584     $install tcpdump python-scapy
585
586     # Install oftest:
587     cd $BUILD_DIR/
588     git clone git://github.com/floodlight/oftest
589 }
590
591 # Install cbench
592 function cbench {
593     echo "Installing cbench..."
594
595     if [ "$DIST" = "Fedora" -o "$DIST" = "RedHatEnterpriseServer" ]; then
596         $install net-snmp-devel libpcap-devel libconfig-devel
597         elif [ "$DIST" = "SUSE LINUX"  ]; then
598                 $install net-snmp-devel libpcap-devel libconfig-devel
599     else
600         $install libsnmp-dev libpcap-dev libconfig-dev
601     fi
602     cd $BUILD_DIR/
603     # was:  git clone git://gitosis.stanford.edu/oflops.git
604     # Use our own fork on github for now:
605     git clone git://github.com/mininet/oflops
606     cd oflops
607     sh boot.sh || true # possible error in autoreconf, so run twice
608     sh boot.sh
609     ./configure --with-openflow-src-dir=$BUILD_DIR/openflow
610     make
611     sudo make install || true # make install fails; force past this
612 }
613
614 function vm_other {
615     echo "Doing other Mininet VM setup tasks..."
616
617     # Remove avahi-daemon, which may cause unwanted discovery packets to be
618     # sent during tests, near link status changes:
619     echo "Removing avahi-daemon"
620     $remove avahi-daemon
621
622     # was: Disable IPv6.  Add to /etc/modprobe.d/blacklist:
623     #echo "Attempting to disable IPv6"
624     #if [ "$DIST" = "Ubuntu" ]; then
625     #    BLACKLIST=/etc/modprobe.d/blacklist.conf
626     #else
627     #    BLACKLIST=/etc/modprobe.d/blacklist
628     #fi
629     #sudo sh -c "echo 'blacklist net-pf-10\nblacklist ipv6' >> $BLACKLIST"
630     echo "Disabling IPv6"
631     # Disable IPv6
632     if ! grep 'disable_ipv6' /etc/sysctl.conf; then
633         echo 'Disabling IPv6'
634         echo '
635 # Mininet: disable IPv6
636 net.ipv6.conf.all.disable_ipv6 = 1
637 net.ipv6.conf.default.disable_ipv6 = 1
638 net.ipv6.conf.lo.disable_ipv6 = 1' | sudo tee -a /etc/sysctl.conf > /dev/null
639     fi
640     # Since the above doesn't disable neighbor discovery, also do this:
641     if ! grep 'ipv6.disable' /etc/default/grub; then
642         sudo sed -i -e \
643         's/GRUB_CMDLINE_LINUX_DEFAULT="/GRUB_CMDLINE_LINUX_DEFAULT="ipv6.disable=1 /' \
644         /etc/default/grub
645         sudo update-grub
646     fi
647     # Disabling IPv6 breaks X11 forwarding via ssh
648     line='AddressFamily inet'
649     file='/etc/ssh/sshd_config'
650     echo "Adding $line to $file"
651     if ! grep "$line" $file > /dev/null; then
652         echo "$line" | sudo tee -a $file > /dev/null
653     fi
654
655     # Enable command auto completion using sudo; modify ~/.bashrc:
656     sed -i -e 's|# for examples$|&\ncomplete -cf sudo|' ~/.bashrc
657
658     # Install tcpdump, cmd-line packet dump tool.  Also install gitk,
659     # a graphical git history viewer.
660     $install tcpdump gitk
661
662     # Install common text editors
663     $install vim nano emacs
664
665     # Install NTP
666     $install ntp
667
668     # Install vconfig for VLAN example
669     if [ "$DIST" = "Fedora" -o "$DIST" = "RedHatEnterpriseServer" ]; then
670         $install vconfig
671     else
672         $install vlan
673     fi
674
675     # Set git to colorize everything.
676     git config --global color.diff auto
677     git config --global color.status auto
678     git config --global color.branch auto
679
680     # Reduce boot screen opt-out delay. Modify timeout in /boot/grub/menu.lst to 1:
681     if [ "$DIST" = "Debian" ]; then
682         sudo sed -i -e 's/^timeout.*$/timeout         1/' /boot/grub/menu.lst
683     fi
684
685     # Clean unneeded debs:
686     rm -f ~/linux-headers-* ~/linux-image-*
687 }
688
689 # Script to copy built OVS kernel module to where modprobe will
690 # find them automatically.  Removes the need to keep an environment variable
691 # for insmod usage, and works nicely with multiple kernel versions.
692 #
693 # The downside is that after each recompilation of OVS you'll need to
694 # re-run this script.  If you're using only one kernel version, then it may be
695 # a good idea to use a symbolic link in place of the copy below.
696 function modprobe {
697     echo "Setting up modprobe for OVS kmod..."
698     set +o nounset
699     if [ -z "$OVS_KMODS" ]; then
700       echo "OVS_KMODS not set. Aborting."
701     else
702       sudo cp $OVS_KMODS $DRIVERS_DIR
703       sudo depmod -a ${KERNEL_NAME}
704     fi
705     set -o nounset
706 }
707
708 function all {
709     if [ "$DIST" = "Fedora" ]; then
710         printf "\nFedora 18+ support (still work in progress):\n"
711         printf " * Fedora 18+ has kernel 3.10 RPMS in the updates repositories\n"
712         printf " * Fedora 18+ has openvswitch 1.10 RPMS in the updates repositories\n"
713         printf " * the install.sh script options [-bfnpvw] should work.\n"
714         printf " * for a basic setup just try:\n"
715         printf "       install.sh -fnpv\n\n"
716         exit 3
717     fi
718     echo "Installing all packages except for -eix (doxypy, ivs, nox-classic)..."
719     kernel
720     mn_deps
721     # Skip mn_dev (doxypy/texlive/fonts/etc.) because it's huge
722     # mn_dev
723     of
724     install_wireshark
725     ovs
726     # We may add ivs once it's more mature
727     # ivs
728     # NOX-classic is deprecated, but you can install it manually if desired.
729     # nox
730     pox
731     oftest
732     cbench
733     echo "Enjoy Mininet!"
734 }
735
736 # Restore disk space and remove sensitive files before shipping a VM.
737 function vm_clean {
738     echo "Cleaning VM..."
739     sudo apt-get clean
740     sudo apt-get autoremove
741     sudo rm -rf /tmp/*
742     sudo rm -rf openvswitch*.tar.gz
743
744     # Remove sensistive files
745     history -c  # note this won't work if you have multiple bash sessions
746     rm -f ~/.bash_history  # need to clear in memory and remove on disk
747     rm -f ~/.ssh/id_rsa* ~/.ssh/known_hosts
748     sudo rm -f ~/.ssh/authorized_keys*
749
750     # Remove SSH keys and regenerate on boot
751     echo 'Removing SSH keys from /etc/ssh/'
752     sudo rm -f /etc/ssh/*key*
753     if ! grep mininet /etc/rc.local >& /dev/null; then
754         sudo sed -i -e "s/exit 0//" /etc/rc.local
755         echo '
756 # mininet: regenerate ssh keys if we deleted them
757 if ! stat -t /etc/ssh/*key* >/dev/null 2>&1; then
758     /usr/sbin/dpkg-reconfigure openssh-server
759 fi
760 exit 0
761 ' | sudo tee -a /etc/rc.local > /dev/null
762     fi
763
764     # Remove Mininet files
765     #sudo rm -f /lib/modules/python2.5/site-packages/mininet*
766     #sudo rm -f /usr/bin/mnexec
767
768     # Clear optional dev script for SSH keychain load on boot
769     rm -f ~/.bash_profile
770
771     # Clear git changes
772     git config --global user.name "None"
773     git config --global user.email "None"
774
775     # Note: you can shrink the .vmdk in vmware using
776     # vmware-vdiskmanager -k *.vmdk
777     echo "Zeroing out disk blocks for efficient compaction..."
778     time sudo dd if=/dev/zero of=/tmp/zero bs=1M || true
779     sync ; sleep 1 ; sync ; sudo rm -f /tmp/zero
780
781 }
782
783 function usage {
784     printf '\nUsage: %s [-abcdfhikmnprtvVwxy03]\n\n' $(basename $0) >&2
785
786     printf 'This install script attempts to install useful packages\n' >&2
787     printf 'for Mininet. It should (hopefully) work on Ubuntu 11.10+\n' >&2
788     printf 'If you run into trouble, try\n' >&2
789     printf 'installing one thing at a time, and looking at the \n' >&2
790     printf 'specific installation function in this script.\n\n' >&2
791
792     printf 'options:\n' >&2
793     printf -- ' -a: (default) install (A)ll packages - good luck!\n' >&2
794     printf -- ' -b: install controller (B)enchmark (oflops)\n' >&2
795     printf -- ' -c: (C)lean up after kernel install\n' >&2
796     printf -- ' -d: (D)elete some sensitive files from a VM image\n' >&2
797     printf -- ' -e: install Mininet d(E)veloper dependencies\n' >&2
798     printf -- ' -f: install Open(F)low\n' >&2
799     printf -- ' -h: print this (H)elp message\n' >&2
800     printf -- ' -i: install (I)ndigo Virtual Switch\n' >&2
801     printf -- ' -k: install new (K)ernel\n' >&2
802     printf -- ' -m: install Open vSwitch kernel (M)odule from source dir\n' >&2
803     printf -- ' -n: install Mini(N)et dependencies + core files\n' >&2
804     printf -- ' -p: install (P)OX OpenFlow Controller\n' >&2
805     printf -- ' -r: remove existing Open vSwitch packages\n' >&2
806     printf -- ' -s <dir>: place dependency (S)ource/build trees in <dir>\n' >&2
807     printf -- ' -t: complete o(T)her Mininet VM setup tasks\n' >&2
808     printf -- ' -v: install Open (V)switch\n' >&2
809     printf -- ' -V <version>: install a particular version of Open (V)switch on Ubuntu\n' >&2
810     printf -- ' -w: install OpenFlow (W)ireshark dissector\n' >&2
811     printf -- ' -y: install R(y)u Controller\n' >&2
812     printf -- ' -x: install NO(X) Classic OpenFlow controller\n' >&2
813     printf -- ' -0: (default) -0[fx] installs OpenFlow 1.0 versions\n' >&2
814     printf -- ' -3: -3[fx] installs OpenFlow 1.3 versions\n' >&2
815     exit 2
816 }
817
818 OF_VERSION=1.0
819
820 if [ $# -eq 0 ]
821 then
822     all
823 else
824     while getopts 'abcdefhikmnprs:tvV:wxy03' OPTION
825     do
826       case $OPTION in
827       a)    all;;
828       b)    cbench;;
829       c)    kernel_clean;;
830       d)    vm_clean;;
831       e)    mn_dev;;
832       f)    case $OF_VERSION in
833             1.0) of;;
834             1.3) of13;;
835             *)  echo "Invalid OpenFlow version $OF_VERSION";;
836             esac;;
837       h)    usage;;
838       i)    ivs;;
839       k)    kernel;;
840       m)    modprobe;;
841       n)    mn_deps;;
842       p)    pox;;
843       r)    remove_ovs;;
844       s)    mkdir -p $OPTARG; # ensure the directory is created
845             BUILD_DIR="$( cd -P "$OPTARG" && pwd )"; # get the full path
846             echo "Dependency installation directory: $BUILD_DIR";;
847       t)    vm_other;;
848       v)    ovs;;
849       V)    OVS_RELEASE=$OPTARG;
850             ubuntuOvs;;
851       w)    install_wireshark;;
852       x)    case $OF_VERSION in
853             1.0) nox;;
854             1.3) nox13;;
855             *)  echo "Invalid OpenFlow version $OF_VERSION";;
856             esac;;
857       y)    ryu;;
858       0)    OF_VERSION=1.0;;
859       3)    OF_VERSION=1.3;;
860       ?)    usage;;
861       esac
862     done
863     shift $(($OPTIND - 1))
864 fi