Changes between Version 1 and Version 2 of GENIExperimenter/Tutorials/ClickExample/Execute


Ignore:
Timestamp:
03/17/13 02:46:36 (6 years ago)
Author:
nriga@bbn.com
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • GENIExperimenter/Tutorials/ClickExample/Execute

    v1 v2  
    1717 </table>
    1818}}}
     19
     20== 3. Configure your routers ==
     21Once our sliver is ready we will go ahead and configure our click routers. In this example we have 4 routers, so instead of logging into each one of them and configuring it, we are going to use remote execution and configure them from our VM.
     22
     23First lets reset our environment:
     24{{{
     25cd
     26rm .ssh/config
     27touch .ssh/config
     28}}}
     29
     30=== 3a. Login and remote execution ===
     31Run the `readyToLogin.py` script to get information about logging in to nodes. The script has a lot of output so lets put that in a file so that we can easily search for the information we want.
     32
     33{{{
     34readyToLogin.py -a pg-utah <slicename> > login.out 2>&1
     35}}}
     36
     37You'll get a big chunk of information, but you're interested in the '''ssh configuration info''' information near the end.
     38
     39{{{
     40... <lots of output> ...
     41================================================================================
     42SSH CONFIGURATION INFO for User inki
     43================================================================================
     44 
     45Host left
     46  Port 30778
     47  HostName pc403.emulab.net
     48  User inki
     49  IdentityFile /home/geni/.ssh/geni_key
     50
     51Host hostB
     52  Port 30779
     53  HostName pc490.emulab.net
     54  User inki
     55  IdentityFile /home/geni/.ssh/geni_key
     56
     57Host hostA
     58  Port 30778
     59  HostName pc545.emulab.net
     60  User inki
     61  IdentityFile /home/geni/.ssh/geni_key
     62
     63Host bottom
     64  Port 30778
     65  HostName pc490.emulab.net
     66  User inki
     67  IdentityFile /home/geni/.ssh/geni_key
     68 
     69Host right
     70  Port 30778
     71  HostName pc411.emulab.net
     72  User inki
     73  IdentityFile /home/geni/.ssh/geni_key
     74 
     75Host top
     76  Port 30779
     77  HostName pc545.emulab.net
     78  User inki
     79  IdentityFile /home/geni/.ssh/geni_key
     80
     81...<more output>...
     82}}}
     83
     84Copy all the above information and paste it into your `.ssh/config` file, then you can very easily login into your nodes, just by using the nickname (client_id) of the nodes.
     85
     86Your `~/.ssh/config` file should look like
     87{{{
     88IdentityFile /home/geni/.ssh/geni_key
     89Host left
     90  Port 30778
     91  HostName pc403.emulab.net
     92  User inki
     93  IdentityFile /home/geni/.ssh/geni_key
     94 
     95Host hostB
     96  Port 30779
     97  HostName pc490.emulab.net
     98  User inki
     99  IdentityFile /home/geni/.ssh/geni_key
     100
     101Host hostA
     102  Port 30778
     103  HostName pc545.emulab.net
     104  User inki
     105  IdentityFile /home/geni/.ssh/geni_key
     106
     107Host bottom
     108  Port 30778
     109  HostName pc490.emulab.net
     110  User inki
     111  IdentityFile /home/geni/.ssh/geni_key
     112
     113Host right
     114  Port 30778
     115  HostName pc411.emulab.net
     116  User inki
     117  IdentityFile /home/geni/.ssh/geni_key
     118
     119Host top
     120  Port 30779
     121  HostName pc545.emulab.net
     122  User inki
     123  IdentityFile /home/geni/.ssh/geni_key
     124
     125}}}
     126
     127Let's login to our two hosts, the nicknames are `hostA` and `hostB`
     128  i. Open two new terminals
     129  i. In one terminal type
     130  {{{
     131  ssh -A hostA
     132  }}}
     133  and in the other
     134  {{{
     135  ssh -A hostB
     136  }}}
     137==== Test remote execution ====
     138You can execute commands in a remote host using `ssh`. To do this just follow your ssh command with the command you want to execute in quotes.
     139  i. In your local terminal type :
     140  {{{
     141  ssh -A top "ls -a"
     142  }}}
     143  This will list all the files under the home directory on host `top`. The output should look like:
     144  {{{
     145geni@geni-VirtualBox:~$ ssh -A top "ls -a"
     146.
     147..
     148.bash_logout
     149.bash_profile
     150.bashrc
     151.forward
     152.kshrc
     153.ssh
     154.zshrc
     155  }}}
     156
     157If you get something similar you are all set for controlling your nodes from your computer.
     158
     159=== 3b. Configure your routers ===
     160We are going to use remote execution to configure our routers.
     161  i. On a local terminal run the following command four times, each time substituting the <router_nickname> with one of the top, bottom, left, right:
     162  {{{
     163  geni@geni-VirtualBox:~$ ssh -A <router_nickname> "/local/click-example/extractClickConfig.py "
     164  }}}
     165  You'll get output something like this:
     166  {{{
     167Your host information:
     168        hostA: hostA.StupidSliceName.emulab-net.emulab.net pc347.emulab.net
     169        top: top.StupidSliceName.emulab-net.emulab.net pc336.emulab.net
     170        left: left.StupidSliceName.emulab-net.emulab.net pc358.emulab.net
     171        right: right.StupidSliceName.emulab-net.emulab.net pc278.emulab.net
     172        bottom: bottom.StupidSliceName.emulab-net.emulab.net pc348.emulab.net
     173        hostB: hostB.StupidSliceName.emulab-net.emulab.net pc353.emulab.net
     174Done.
     175}}}
     176  (If you are prompted for a password, check to make sure that you provided the -A switch in your ssh command above.)
     177
     178  i. The extractClickConfig script produces router configurations for your experiment. It also creates a diagram of your experiment. Get a copy locally from one of the routers, by typing in a local terminal:
     179  {{{
     180 scp top:myslice.png ./
     181}}}
     182  i. View the diagram by typing :
     183  {{{
     184  eog myslice.png &
     185}}}
     186  Your slice will look something like the one below (see [attachment:myslice.png]). The overall configuration should be the same, with two end hosts, named hostA and hostB, and four routers (top, left, right, bottom) in a diamond configuration. The host names, interface names, and MAC addresses will be different, depending on the actual resources assigned to your slice.
     187
     188[[Image(myslice.png, 25%)]]
     189
     190The four routers interconnected by solid lines are your "core network," which will run a non-standard, non-IP protocol. The dashed lines out to the end hosts carry standard IP traffic.
     191
     192== 4. Turn off internet protocol ==
     193
     194At this point, your network is still running IP. You can check by running a ping. In your '''hosta''' terminal window, run this command.
     195
     196{{{
     197ping -c 3 hostb
     198}}}
     199
     200The command should succeed, with output like this:
     201
     202{{{
     203PING hostB-link-B (10.10.6.2) 56(84) bytes of data.
     20464 bytes from hostB-link-B (10.10.6.2): icmp_seq=1 ttl=61 time=1.38 ms
     20564 bytes from hostB-link-B (10.10.6.2): icmp_seq=2 ttl=61 time=1.19 ms
     20664 bytes from hostB-link-B (10.10.6.2): icmp_seq=3 ttl=61 time=1.53 ms
     207
     208--- hostB-link-B ping statistics ---
     2093 packets transmitted, 3 received, 0% packet loss, time 2004ms
     210rtt min/avg/max/mdev = 1.193/1.370/1.531/0.138 ms
     211}}}
     212
     213Since our experiment doesn't want IP, let's turn it off :
     214  i. On a local terminal run the following command four times, each time substituting the <router_nickname> with one of the top, bottom, left, right:
     215  {{{
     216  ssh -A <router_nickname> "sh ./stopIP.sh"
     217}}}
     218
     219  You'll get output like this (the interface names may be different):
     220  {{{
     221Disabling IP on interface mv10.9
     222Disabling IP on interface mv10.10
     223}}}
     224
     225  i. Verify that IP is really off, try another ping. On '''hosta''':
     226  {{{
     227  ping -c 3 hostb
     228}}}
     229  The command should take twelve seconds to time out, then fail with output like this:
     230  {{{
     231PING hostB-link-B (10.10.6.2) 56(84) bytes of data.
     232
     233--- hostB-link-B ping statistics ---
     2343 packets transmitted, 0 received, 100% packet loss, time 11999ms
     235}}}
     236
     237== 5. Start your routers ==
     238
     239The extractor script produces a click configuration file for each of your routers. 
     240  i. On a local terminal run the following command four times, each time substituting the <router_nickname> with one of the top, bottom, left, right:
     241  {{{
     242  ssh -A <router_nickname> "sh ./startClick.sh"
     243}}}
     244  You'll get output like this. (Don't worry about the warning messages, Click is just reminding you that you have no IP addresses in your core network.) The output of the click router is redirected to `/tmp/click.out` on each host.
     245
     246  {{{
     247Stopping any running Click routers
     248Starting Click router
     249top.click:34: While initializing ‘FromDevice@18 :: FromDevice’:
     250  warning: eth2: no IPv4 address assigned
     251top.click:35: While initializing ‘FromDevice@21 :: FromDevice’:
     252  warning: eth4: no IPv4 address assigned
     253}}}
     254
     255Congratulations! You are now running a non-IP core network on your four routers, along with a (primitive) non-IP multipath routing algorithm. You're ready to experiment with this configuration.
     256
     257== 6. Send some traffic ==
     258
     259Now you'll use your two edge hosts, '''hostA''' and '''hostB''' to send traffic along your network.  Since these end hosts are not running your modified protocol, they'll rely on the '''top''' and '''bottom''' routers to transform their IP packets into your modified protocol on entry to the core network and back into IP packets on exit.
     260  i. In your terminal window on '''hostB''', instruct '''nc''' to listen for a UDP connection on port 24565 (or some other port that catches your fancy).
     261  {{{
     262[mberman@hostb ~]$ nc -ul 24565
     263}}}
     264  i. Connect to it from your terminal window on '''hostA''':
     265  {{{
     266[mberman@hosta ~]$ nc -u hostb 24565
     267}}}
     268
     269You've established a simple text chat connection. Enter a line of text in either window, and it should appear in the other. Of course to do this, the text is travelling through your core network, using your non-standard protocol and routing. So type a message into each window, and make sure it appears in the other.
     270
     271That's it!  Now, let's look inside to see what's going on.
     272
     273== 7. Looking under the hood ==
     274
     275Please note: the interface names and MAC addresses below are for the sample configuration shown in the figure above. You will want to refer to your network diagram to get the correct interfaces and addresses for your configuration.
     276
     277Let's take a look at what's happening in the four routers in your configuration. There are two basic router configurations. (You can find all of these files on any of your router hosts.)
     278
     279=== 7b. Packet transformation ===
     280
     281  i. The more interesting configuration appears here, in the '''top.click''' configuration file. In a local terminal type:
     282  {{{
     283 ssh -A top "cat top.click"
     284}}}
     285  The output will look like :
     286  {{{
     287// This portion accepts IP packets,
     288// reformats them, and routes them
     289// to an internal router.
     290route :: Classifier(27/01%01,-);
     291
     292modify :: Unstrip(2) ->
     293    StoreData(0, "AliceWasHere3546") ->
     294    route;
     295
     296FromDevice(eth3, PROMISC true) ->
     297    Classifier(12/0800) ->
     298    modify;
     299
     300route[0] -> left :: EtherEncap(0x7744, 00:04:23:b7:14:76, 00:04:23:b7:18:fa) ->
     301    SimpleQueue ->
     302    Print(outL) ->
     303    ToDevice(eth2);
     304
     305route[1] -> right :: EtherEncap(0x7744, 00:04:23:b7:1c:e0, 00:04:23:b7:19:2e) ->
     306    SimpleQueue ->
     307    Print(outR) ->
     308    ToDevice(eth4);
     309
     310// This portion accepts non-IP packets
     311// with an ether type of 0x7744
     312// from an internal router, restores
     313// them to IP format, and forwards.
     314restore :: SimpleQueue ->
     315    Strip(30) ->
     316    EtherEncap(0x800, 00:04:23:b7:14:77, 00:04:23:b7:20:00) ->
     317    ToDevice(eth3);
     318
     319FromDevice(eth2) -> Classifier(12/7744) -> Print(inL) -> restore;
     320FromDevice(eth4) ->  Classifier(12/7744) -> Print(inR) -> restore;
     321}}}
     322
     323  As indicated in the comments, the top portion of the configuration listens ('''!FromDevice''') for IP packets arriving on the interface connected to '''hostA''' (that's '''eth3''' in this example). It then creates a new 16-byte field at the head of the packet (two bytes added by the '''Unstrip''' operation, plus the existing 14-byte Ethernet header. It fills that field with what could be important routing instructions, but in this case is just graffiti ('''!StoreData'''). The '''route''' operation then routes the packet via either the '''left''' or '''right''' router toward '''hostB'''. In either case, it wraps the packet in a fresh Ethernet header ('''!EtherEncap''') with a distinctive ether type code (0x7744), logs the new packet on its way out ('''Print''') and sends it out on the correct interface ('''!ToDevice''').
     324
     325  The bottom portion of the configuration is intended for packets coming out of the core network to '''hostA'''.  It accepts packets from either the '''left''' or '''right''' router, logs them, strips off thirty bytes (Ethernet header plus your 16-byte new header field), puts on a fresh Ethernet header, and sends them along to '''hostA'''.
     326
     327  The configuration for the '''bottom''' router is exactly symmetric, routing packets between '''hostB''' and the core network, but using different graffiti.
     328
     329=== 7b. Simple Forwarding ===
     330
     331The '''left''' router configuration is much simpler.  In a local terminal type:
     332{{{
     333 ssh -A left "cat left.click"
     334}}}
     335  The output will look like :
     336
     337{{{
     338// Copy packets from top to bottom.
     339FromDevice(eth2) ->
     340    StoreEtherAddress(00:04:23:b7:42:b6, dst) ->
     341    StoreEtherAddress(00:04:23:b7:18:fb, src) ->
     342    SimpleQueue ->
     343    Print(top) ->
     344    ToDevice(eth3);
     345// Copy packets from bottom to top.
     346FromDevice(eth3) ->
     347    StoreEtherAddress(00:04:23:b7:14:76, dst) ->
     348    StoreEtherAddress(00:04:23:b7:18:fa, src) ->
     349    SimpleQueue ->
     350    Print(bottom) ->
     351    ToDevice(eth2);
     352}}}
     353
     354This configuration just blindly forwards packets. It picks up any packet from the '''top''' router, updates the Ethernet header, and passes it along to the '''bottom''' router. The same applies in the reverse direction.  Again, the configuration for the '''right''' router is exactly analogous.
     355
     356=== 7c. Monitoring your core network ===
     357
     358Let's watch how the packets travel through the network.
     359  i. In a local terminal type:
     360  {{{
     361  ssh -A top "tail -f /tmp/click.log"
     362}}}
     363  i. Go to your window for hostA, where your '''nc''' command is still running. Type a message into this window. You should see a log message in three of your four router windows. In this example, you might see:
     364  i. In the local terminal you will see:
     365  {{{
     366outR:   76 | 000423b7 192e0004 23b71ce0 7744416c 69636557 61734865
     367}}}
     368  This log entry says that the '''top''' router received a packet from '''hostA''', modified it, and sent it out to the '''right''' router. If the entry started with '''outL''', that would indicate that it sent the packet out to the '''left''' router. Let's look a bit at the start of the packet (the first 24 bytes are logged). It starts with an Ethernet header. The first six bytes are the MAC address of the destination interface, that's 00:04:23:B7:19:2E, the MAC address of '''eth4''' on '''right'''. The next six bytes are the MAC address of the source interface, 00:04:23:B7:1C:E0, or '''eth4''' on '''top'''. Next comes your ether type, 0x7744. The remaining bytes, "416c 69636557 61734865" are the start of the first field in your new protocol, "!AliceWasHe" in ASCII.
     369  i. Try typing a few different lines to hostA. You should see some packets routed to the left and some to the right. The routing decision is based on the '''route :: Classifier(27/01%01,-);''' entry in the '''top''' router configuration. Here, the router is looking at the low-order bit of the checksum on the initial IP packet (now at byte position 27 with the addition of the new sixteen byte field at the start of the header). Packets with odd checksums go to the left; those with even checksums go right.