Thursday 23 May 2013

OpenFlow Switch on Raspberry Pi Part 3: Configuration and getting it running

In part 1 I showed what hardware you need to turn your Raspberry Pi into an OpenFlow switch by  adding USB to Ethernet adaptors.

In part 2 I showed how to install Erlang and install the LINC OpenFlow switch

In this part we start with configuring the switch.

The first thing we need to do is identify what networking ports we have on our Pi.

We use the command ifconfig -a to find out what Ethernet ports we have

pi@raspberrypi ~ $ ifconfig -a

eth0      Link encap:Ethernet  HWaddr b8:27:eb:21:08:6a
          inet addr:192.168.1.19  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:121 errors:0 dropped:0 overruns:0 frame:0
          TX packets:83 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:11559 (11.2 KiB)  TX bytes:11040 (10.7 KiB)

eth1      Link encap:Ethernet  HWaddr 00:e0:4c:53:44:58
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0  carrier:0  
          collisions:0  txqueuelen:1000                                                                               
           RX bytes:0 (0.0 B)  TX bytes:0 (0.0B)   

eth2      Link encap:Ethernet  HWaddr 00:e0:4c:53:44:58
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

wlan0     Link encap:Ethernet  HWaddr 00:0b:81:89:5e:bf
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)


Port eth0 is the native Ethernet port on the Pi and the USB based Ethernet ports are showing up as eth1, eth2 and wlan0.  If you've added more or different ports for your hardware, your port numbers will differ.

We now need to edit the LINC config file so that it knows what ports it has access to.
If the version you have downloaded is higher than 1.0 you'll need to change the line below

pi@raspberrypi ~/LINC-Switch $ sudo vi rel/linc/releases/1.0/sys.config

We now need to edit the section of the file to declare the ports which form part of the switch

       {ports,
        [
         %% - regular hardware interface
         {port, 1, [{interface, "eth1"}]},
         {port, 2, [{interface, "eth2"}]},
         {port, 3, [{interface, "wlan0"}]},
         {port, 4, [{interface, "eth0"}]}
         %% - hardware interface with explicit type
         %% {port, 1, [{interface, "net0"}, {type, eth}]},
         %% - regular tap interface
         %% {port, 2, [{interface, "tap0"}]},
         %% - tap interface under MacOSX with dynamically assigned IP
         %% {port, 3, [{interface, "tap1"}, {ip, "10.0.0.1"}]},
         %% - tap interface with explicit type
         %% {port, 4, [{interface, "net1"}, {type, tap}]}
        ]},

Note that the last active port shouldn't have a comma after it

We can now start the OpenFlow switch for the first time

pi@raspberrypi ~/LINC-Switch $ sudo rel/linc/bin/linc console

Exec: /home/pi/LINC-Switch/rel/linc/erts-5.9.3.1/bin/erlexec -boot /home/pi/LINC-Switch/rel/linc/releases/1.0/linc -mode embedded -config /home/pi/LINC-Switch/rel/linc/releases/1.0/sys.config -args_file /home/pi/LINC-Switch/rel/linc/releases/1.0/vm.args -- console
Root: /home/pi/LINC-Switch/rel/linc
Erlang R15B03 (erts-5.9.3.1) [source] [async-threads:0] [kernel-poll:false]

21:18:47.473 [info] Application lager started on node linc@raspberrypi
21:18:47.483 [info] Application ssh started on node linc@raspberrypi
21:18:47.542 [info] Application enetconf started on node linc@raspberrypi
21:18:47.557 [info] Application linc started on node linc@raspberrypi
Eshell V5.9.3.1  (abort with ^G)
(linc@raspberrypi)1> 21:18:47.957 [info] Created port: {port,4,[{queues_status,disabled},{queues,[]},{config,{port_configuration,undefined,up,false,false,false}},{features,{features,undefined,'100Mb-FD',true,copper,unsupported}},{interface,"eth0"}]}
21:18:48.197 [info] Created port: {port,3,[{queues_status,disabled},{queues,[]},{config,{port_configuration,undefined,up,false,false,false}},{features,{features,undefined,'100Mb-FD',true,copper,unsupported}},{queues,[]},{interface,"wlan0"}]}
21:18:48.435 [info] Created port: {port,2,[{queues_status,disabled},{queues,[]},{config,{port_configuration,undefined,up,false,false,false}},{features,{features,undefined,'100Mb-FD',true,copper,unsupported}},{queues,[]},{interface,"eth2"}]}
21:18:48.704 [info] Created port: {port,1,[{queues_status,disabled},{queues,[]},{config,{port_configuration,undefined,up,false,false,false}},{features,{features,undefined,'100Mb-FD',true,copper,unsupported}},{queues,[]},{interface,"eth1"}]}

(linc@raspberrypi)1>
You can see LINC has created the ports defined in the config file and ended with the Erlang prompt.

OK. Let's shutdown the switch. We use the Erlang command  init:stop().

(linc@raspberrypi)1> init:stop().
ok

In the next post we'll get an OpenFlow controller running and start talking to the switch.

8 comments:

  1. for anyone else reading this - setup your ports under the "capable_switch_ports" section rather than the "ports" section.

    ReplyDelete
  2. i followed the steps in the posts but when I do the sudo rel/linc/bin/linc console command, I keep getting a bad match error. What can be wrong in my setup?

    Here is the console output:

    pi@raspberrypi ~/LINC-Switch $ sudo rel/linc/bin/linc console
    Exec: /home/pi/LINC-Switch/rel/linc/erts-5.10.3/bin/erlexec -boot /home/pi/LINC-Switch/rel/linc/releases/1.0/linc -mode embedded -config /home/pi/LINC-Switch/rel/linc/releases/1.0/sys.config -args_file /home/pi/LINC-Switch/rel/linc/releases/1.0/vm.args -- console
    Root: /home/pi/LINC-Switch/rel/linc
    Erlang R16B02 (erts-5.10.3) [source-b44b726] [async-threads:10] [kernel-poll:false]

    13:51:41.883 [info] Application lager started on node linc@raspberrypi
    13:51:41.890 [info] Application ssh started on node linc@raspberrypi
    13:51:41.911 [info] Application enetconf started on node linc@raspberrypi
    13:51:41.918 [error] CRASH REPORT Process <0.613.0> with 0 neighbours exited with reason: no match of right hand value false in linc_ofconfig:'-convert_logical_switch/3-fun-0-'/4 line 200 in application_master:init/4 line 133
    Eshell V5.10.3 (abort with ^G)
    (linc@raspberrypi)1> 13:51:41.967 [info] Application linc exited with reason: no match of right hand value false in linc_ofconfig:'-convert_logical_switch/3-fun-0-'/4 line 200
    {"Kernel pid terminated",application_controller,"{application_start_failure,linc,{bad_return,{{linc,start,[normal,[]]},{'EXIT',{{badmatch,false},[{linc_ofconfig,'-convert_logical_switch/3-fun-0-',4,[{file,\"src/linc_ofconfig.erl\"},{line,200}]},{lists,foldl,3,[{file,\"lists.erl\"},{line,1248}]},{linc_ofconfig,convert_logical_switch,3,[{file,\"src/linc_ofconfig.erl\"},{line,199}]},{linc_ofconfig,'-get_linc_logical_switches/0-lc$^0/1-0-',3,[{file,\"src/linc_ofconfig.erl\"},{line,192}]},{linc_ofconfig,read_and_update_startup,0,[{file,\"src/linc_ofconfig.erl\"},{line,347}]},{linc_capable_sup,start_link,0,[{file,\"src/linc_capable_sup.erl\"},{line,48}]},{application_master,start_it_old,4,[{file,\"application_master.erl\"},{line,269}]}]}}}}}"}

    Crash dump was written to: erl_crash.dump
    Kernel pid terminated (application_controller) ({application_start_failure,linc,{bad_return,{{linc,start,[normal,[]]},{'EXIT',{{badmatch,false},[{linc_ofconfig,'-convert_logical_switch/3-fun-0-',4,[

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
  3. I am getting the same...was anyone able to fix it...?

    ReplyDelete
  4. Thanks Matt - mines working (at least not spewing out any errors so far) and the process seems to have successfully started.

    root@PI:/home/pi/LINC-Switch# rel/linc/bin/linc console
    Exec: /home/pi/LINC-Switch/rel/linc/erts-5.9.3.1/bin/erlexec -boot /home/pi/LINC-Switch/rel/linc/releases/1.0/linc -mode embedded -config /home/pi/LINC-Switch/rel/linc/releases/1.0/sys.config -args_file /home/pi/LINC-Switch/rel/linc/releases/1.0/vm.args -- console
    Root: /home/pi/LINC-Switch/rel/linc
    Erlang R15B03 (erts-5.9.3.1) [source] [async-threads:0] [kernel-poll:false]

    03:17:33.206 [info] Application lager started on node linc@PI
    03:17:33.214 [info] Application ssh started on node linc@PI
    03:17:33.240 [info] Application enetconf started on node linc@PI
    03:17:33.258 [info] Application linc started on node linc@PI
    Eshell V5.9.3.1 (abort with ^G)
    (linc@PI)1>

    ReplyDelete
  5. Regarding the crashes above, define the ports in both capable ports and ports sections. This seems to solve the issue. This is what the comments in the config file suggest anyway. Don't use queues.

    ReplyDelete
  6. This comment has been removed by the author.

    ReplyDelete
  7. I've been trying to setup the switch step by step as mentioned in your blog but when i try to edit the sys.config I cannot save the changes and it shows E212: Cant open file for writing every time i try, how to overcome this?

    ReplyDelete