Skip to content

Commit

Permalink
Add new example MultiLearningSwitch.
Browse files Browse the repository at this point in the history
  • Loading branch information
yasuhito committed Feb 9, 2015
1 parent 5e71da5 commit 412f01f
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 19 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Change log

## develop (unreleased)
### New features
* Add new example `MultiLearningSwitch`.


## 0.1.0 (2/9/2015)

### Misc
* The initial release version of hello_trema that runs on [pure-Ruby Trema](https://github.com/trema/trema_ruby).
6 changes: 3 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
GIT
remote: git://github.com/trema/phut.git
revision: 91b98a6fa1d2e5342051df2911b0c1ec5d06d262
revision: 97525671c6963cc22d62af4f1be6735c01cdf4ad
branch: develop
specs:
phut (0.1.0)
Expand All @@ -10,7 +10,7 @@ GIT

GIT
remote: git://github.com/trema/trema_ruby.git
revision: 82aaa786bab37f853dd5e2aca3a095be35b99658
revision: 09cc4ab6078b4a32df06c67f74750ca3609797bc
branch: develop
specs:
trema (0.1.0)
Expand Down Expand Up @@ -73,7 +73,7 @@ GEM
given_core (3.6.0)
sorcerer (>= 0.3.7)
gli (2.12.2)
guard (2.11.1)
guard (2.12.0)
formatador (>= 0.2.4)
listen (~> 2.7)
lumberjack (~> 1.0)
Expand Down
18 changes: 13 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ Learning Switch
[![Dependency Status](http://img.shields.io/gemnasium/trema/learning_switch.svg?style=flat)][gemnasium]
[![Inline docs](http://inch-ci.org/github/trema/learning_switch.png?branch=develop)][inch]

An OpenFlow controller that controls a single OpenFlow switch and
emulates a layer 2 switch.
An OpenFlow controller that emulates layer 2 switches.

[travis]: http://travis-ci.org/trema/learning_switch
[coveralls]: https://coveralls.io/r/trema/learning_switch
Expand All @@ -29,14 +28,15 @@ $ bundle install
Play
----

Run this controller:
The `lib/learning_switch.rb` is an OpenFlow controller implementation
that emulates a layer 2 switch. Run this like so:

```
% bundle exec trema run lib/learning_switch.rb -c trema.conf
```

Send some packets from host1 to host2, and show received packet stats
of host2:
Then send some packets from host1 to host2, and show received packet
stats of host2:

```
% bundle exec trema send_packets --source host1 --dest host2 --n_pkts 10
Expand All @@ -45,4 +45,12 @@ ip_dst,tp_dst,ip_src,tp_src,n_pkts,n_octets
192.168.0.2,1,192.168.0.1,1,10,500
```

The `lib/multi_learning_switch.rb` is an extension to
`lib/learning_switch.rb`. It can emulate multiple OpenFlow switches.

```
% trema run ./lib/multi_learning_switch.rb -c trema.multi.conf
```


Enjoy!
67 changes: 67 additions & 0 deletions features/multi_learning_switch.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
Feature: "Multi Learning Switch" example
Background:
Given a file named ".trema/config" with:
"""
LOG_DIR: .
PID_DIR: .
SOCKET_DIR: .
"""
Given a file named "trema.conf" with:
"""
vswitch('lsw1') { datapath_id '0x1' }
vswitch('lsw2') { datapath_id '0x2' }
vswitch('lsw3') { datapath_id '0x3' }
vswitch('lsw4') { datapath_id '0x4' }
vhost('host1')
vhost('host2')
vhost('host3')
vhost('host4')
link 'lsw1', 'host1'
link 'lsw2', 'host2'
link 'lsw3', 'host3'
link 'lsw4', 'host4'
link 'lsw1', 'lsw2'
link 'lsw2', 'lsw3'
link 'lsw3', 'lsw4'
"""

Scenario: Run
Given I successfully run `trema run ../../lib/multi_learning_switch.rb -c trema.conf -d`
And I run `sleep 10`
When I successfully run `trema send_packets --source host1 --dest host2 --n_pkts 2`
Then the total number of tx packets should be:
| host1 | host2 | host3 | host4 |
| 2 | 0 | 0 | 0 |
And the total number of rx packets should be:
| host1 | host2 | host3 | host4 |
| 0 | 2 | 0 | 0 |
When I successfully run `trema send_packets --source host3 --dest host4 --n_pkts 3`
Then the total number of tx packets should be:
| host1 | host2 | host3 | host4 |
| 2 | 0 | 3 | 0 |
And the total number of rx packets should be:
| host1 | host2 | host3 | host4 |
| 0 | 2 | 0 | 3 |
When I successfully run `trema send_packets --source host4 --dest host1 --n_pkts 2`
Then the total number of tx packets should be:
| host1 | host2 | host3 | host4 |
| 2 | 0 | 3 | 2 |
And the total number of rx packets should be:
| host1 | host2 | host3 | host4 |
| 2 | 2 | 0 | 3 |
When I successfully run `trema send_packets --source host2 --dest host3 --n_pkts 4`
Then the total number of tx packets should be:
| host1 | host2 | host3 | host4 |
| 2 | 4 | 3 | 2 |
And the total number of rx packets should be:
| host1 | host2 | host3 | host4 |
| 2 | 2 | 4 | 3 |
When I successfully run `trema send_packets --source host1 --dest host4 --n_pkts 1`
Then the total number of tx packets should be:
| host1 | host2 | host3 | host4 |
| 3 | 4 | 3 | 2 |
And the total number of rx packets should be:
| host1 | host2 | host3 | host4 |
| 2 | 2 | 4 | 4 |
12 changes: 2 additions & 10 deletions lib/learning_switch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,8 @@ def age_fdb

def flow_mod_and_packet_out(message)
port_no = @fdb.lookup(message.destination_mac)
if port_no
flow_mod message, port_no
packet_out message, port_no
else
flood message
end
flow_mod(message, port_no) if port_no
packet_out(message, port_no || :flood)
end

def flow_mod(message, port_no)
Expand All @@ -47,8 +43,4 @@ def packet_out(message, port_no)
actions: SendOutPort.new(port_no)
)
end

def flood(message)
packet_out message, :flood
end
end
50 changes: 50 additions & 0 deletions lib/multi_learning_switch.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
$LOAD_PATH.unshift __dir__

require 'fdb'

# An OpenFlow controller that emulates multiple layer-2 switches.
class MultiLearningSwitch < Trema::Controller
timer_event :age_fdbs, interval: 5.sec

def start(_argv)
@fdbs = {}
end

def switch_ready(datapath_id)
@fdbs[datapath_id] = FDB.new
end

def packet_in(datapath_id, message)
return if message.destination_mac.reserved?
@fdbs.fetch(datapath_id).learn(message.source_mac, message.in_port)
flow_mod_and_packet_out message
end

def age_fdbs
@fdbs.each_value(&:age)
end

private

def flow_mod_and_packet_out(message)
port_no = @fdbs.fetch(message.dpid).lookup(message.destination_mac)
flow_mod(message, port_no) if port_no
packet_out(message, port_no || :flood)
end

def flow_mod(message, port_no)
send_flow_mod_add(
message.datapath_id,
match: ExactMatch.new(message),
actions: SendOutPort.new(port_no)
)
end

def packet_out(message, port_no)
send_packet_out(
message.datapath_id,
packet_in: message,
actions: SendOutPort.new(port_no)
)
end
end
17 changes: 17 additions & 0 deletions trema.multi.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
vswitch("lsw1") { datapath_id "0x1" }
vswitch("lsw2") { datapath_id "0x2" }
vswitch("lsw3") { datapath_id "0x3" }
vswitch("lsw4") { datapath_id "0x4" }

vhost("host1")
vhost("host2")
vhost("host3")
vhost("host4")

link "lsw1", "host1"
link "lsw2", "host2"
link "lsw3", "host3"
link "lsw4", "host4"
link "lsw1", "lsw2"
link "lsw2", "lsw3"
link "lsw3", "lsw4"

0 comments on commit 412f01f

Please sign in to comment.