trema 0.2.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. data/.gitmodules +3 -0
  2. data/.travis.yml +13 -0
  3. data/.yardopts +4 -0
  4. data/Gemfile +2 -3
  5. data/README.md +43 -97
  6. data/Rakefile +60 -4
  7. data/Rantfile +11 -10
  8. data/cruise.rb +4 -6
  9. data/features/example.packetin_filter_config.feature +10 -10
  10. data/features/example.switch_monitor.feature +14 -2
  11. data/features/step_definitions/kill_steps.rb +2 -2
  12. data/features/step_definitions/{off_steps.rb → killall_steps.rb} +2 -2
  13. data/features/step_definitions/misc_steps.rb +1 -1
  14. data/features/step_definitions/up_steps.rb +30 -0
  15. data/features/trema.feature +1 -0
  16. data/features/trema.run.feature +1 -0
  17. data/locale/README.ja.md +19 -0
  18. data/locale/ja/yard.po +3762 -0
  19. data/locale/yard.pot +3740 -0
  20. data/ruby/extconf.rb +4 -1
  21. data/ruby/trema/action-common.c +3 -17
  22. data/ruby/trema/action-common.h +3 -7
  23. data/ruby/trema/action.rb +33 -0
  24. data/ruby/trema/app.rb +1 -1
  25. data/ruby/trema/barrier-request.c +1 -0
  26. data/ruby/trema/command/run.rb +13 -9
  27. data/ruby/trema/command/usage.rb +1 -0
  28. data/ruby/trema/command/version.rb +1 -1
  29. data/ruby/trema/controller.c +133 -50
  30. data/ruby/trema/controller.rb +2 -2
  31. data/ruby/trema/desc-stats-reply.rb +77 -0
  32. data/ruby/trema/dsl/configuration.rb +3 -14
  33. data/ruby/trema/dsl/rswitch.rb +47 -0
  34. data/ruby/trema/dsl/runner.rb +4 -1
  35. data/ruby/trema/dsl/syntax.rb +11 -8
  36. data/ruby/trema/echo-reply.c +59 -45
  37. data/ruby/trema/echo-reply.h +1 -3
  38. data/ruby/trema/echo-request.c +49 -71
  39. data/ruby/trema/echo-request.h +0 -2
  40. data/ruby/trema/echo.c +99 -0
  41. data/ruby/trema/{action-enqueue.h → echo.h} +6 -7
  42. data/ruby/trema/enqueue.rb +87 -0
  43. data/ruby/trema/error.c +109 -104
  44. data/ruby/trema/error.h +0 -2
  45. data/ruby/trema/features-reply.c +89 -35
  46. data/ruby/trema/features-reply.h +0 -6
  47. data/ruby/trema/features-request.c +63 -37
  48. data/ruby/trema/features-request.h +0 -2
  49. data/ruby/trema/flow-mod.c +149 -0
  50. data/ruby/trema/{action-output.h → flow-mod.h} +6 -6
  51. data/ruby/trema/get-config-request.c +1 -0
  52. data/ruby/trema/hardware-switch.rb +88 -0
  53. data/ruby/trema/hello.c +55 -31
  54. data/ruby/trema/hello.h +0 -2
  55. data/ruby/trema/ip.rb +12 -2
  56. data/ruby/trema/logger.rb +29 -0
  57. data/ruby/trema/mac.rb +57 -36
  58. data/ruby/trema/match.c +7 -9
  59. data/ruby/trema/monkey-patch/integer/ranges.rb +0 -2
  60. data/ruby/trema/network-component.rb +1 -1
  61. data/ruby/trema/open-vswitch.rb +2 -2
  62. data/ruby/trema/openflow-switch.rb +3 -54
  63. data/ruby/trema/{packet_in.c → packet-in.c} +262 -175
  64. data/ruby/trema/{packet_in.h → packet-in.h} +0 -2
  65. data/ruby/trema/packet-queue.rb +4 -3
  66. data/ruby/trema/port-mod.c +8 -9
  67. data/ruby/trema/port-status-add.rb +60 -0
  68. data/ruby/trema/port-status-delete.rb +60 -0
  69. data/ruby/trema/port-status-modify.rb +60 -0
  70. data/ruby/trema/port-status.c +48 -15
  71. data/ruby/trema/port-status.h +6 -8
  72. data/ruby/trema/port.c +63 -8
  73. data/ruby/trema/queue-get-config-request.c +1 -0
  74. data/ruby/trema/ruby-switch.rb +62 -0
  75. data/ruby/trema/send-out-port.rb +97 -0
  76. data/ruby/trema/set-config.c +1 -0
  77. data/ruby/trema/set-eth-addr.rb +45 -0
  78. data/ruby/trema/set-eth-dst-addr.rb +54 -0
  79. data/ruby/trema/set-eth-src-addr.rb +54 -0
  80. data/ruby/trema/set-ip-addr.rb +47 -0
  81. data/ruby/trema/set-ip-dst-addr.rb +53 -0
  82. data/ruby/trema/set-ip-src-addr.rb +52 -0
  83. data/ruby/trema/set-ip-tos.rb +63 -0
  84. data/ruby/trema/set-transport-dst-port.rb +53 -0
  85. data/ruby/trema/set-transport-port.rb +52 -0
  86. data/ruby/trema/set-transport-src-port.rb +54 -0
  87. data/ruby/trema/set-vlan-priority.rb +65 -0
  88. data/ruby/trema/set-vlan-vid.rb +64 -0
  89. data/ruby/trema/shell/down.rb +1 -1
  90. data/ruby/trema/shell/link.rb +4 -4
  91. data/ruby/trema/shell/run.rb +8 -6
  92. data/ruby/trema/shell/up.rb +3 -3
  93. data/ruby/trema/stats-reply.c +27 -2
  94. data/ruby/trema/stats-request.c +64 -23
  95. data/ruby/trema/strip-vlan-header.rb +41 -0
  96. data/ruby/trema/switch.c +196 -0
  97. data/ruby/trema/{action-vendor.h → switch.h} +5 -7
  98. data/ruby/trema/switch.rb +28 -9
  99. data/ruby/trema/trema-ruby-utils.c +66 -0
  100. data/ruby/trema/{action-set-dl-src.h → trema-ruby-utils.h} +9 -11
  101. data/ruby/trema/trema.c +61 -61
  102. data/ruby/trema/vendor-action.rb +73 -0
  103. data/ruby/trema/vendor.c +121 -52
  104. data/ruby/trema/vendor.h +6 -10
  105. data/ruby/trema/version.rb +1 -1
  106. data/spec/spec_helper.rb +1 -1
  107. data/spec/support/action.rb +52 -0
  108. data/spec/support/mandatory-option.rb +56 -0
  109. data/spec/support/openflow-message.rb +91 -7
  110. data/spec/support/port-status.rb +38 -0
  111. data/spec/trema/controller_spec.rb +0 -26
  112. data/spec/trema/dsl/configuration_spec.rb +3 -3
  113. data/spec/trema/dsl/runner_spec.rb +12 -32
  114. data/spec/trema/dsl/syntax_spec.rb +2 -11
  115. data/spec/trema/echo-reply_spec.rb +49 -14
  116. data/spec/trema/echo-request_spec.rb +86 -34
  117. data/spec/trema/enqueue_spec.rb +76 -0
  118. data/spec/trema/error_spec.rb +43 -58
  119. data/spec/trema/features-reply_spec.rb +58 -24
  120. data/spec/trema/features-request_spec.rb +54 -28
  121. data/spec/trema/flow-mod_spec.rb +99 -0
  122. data/spec/trema/{openflow-switch_spec.rb → hardware-switch_spec.rb} +3 -3
  123. data/spec/trema/hello_spec.rb +28 -14
  124. data/spec/trema/ip_spec.rb +54 -0
  125. data/spec/trema/mac_spec.rb +49 -64
  126. data/spec/trema/match_spec.rb +1 -1
  127. data/spec/trema/open-vswitch_spec.rb +7 -7
  128. data/spec/trema/packet-in_spec.rb +73 -16
  129. data/spec/trema/port-status-add_spec.rb +32 -0
  130. data/spec/trema/port-status-delete_spec.rb +32 -0
  131. data/spec/trema/port-status-modify_spec.rb +71 -0
  132. data/spec/trema/port-status_spec.rb +5 -76
  133. data/spec/trema/{action-output_spec.rb → send-out-port_spec.rb} +20 -47
  134. data/spec/trema/set-eth-dst-addr_spec.rb +75 -0
  135. data/spec/trema/set-eth-src-addr_spec.rb +72 -0
  136. data/spec/trema/set-ip-dst-addr_spec.rb +58 -0
  137. data/spec/trema/set-ip-src-addr_spec.rb +58 -0
  138. data/spec/trema/set-ip-tos_spec.rb +65 -0
  139. data/spec/trema/set-transport-dst-port_spec.rb +65 -0
  140. data/spec/trema/set-transport-src-port_spec.rb +65 -0
  141. data/spec/trema/set-vlan-priority_spec.rb +65 -0
  142. data/spec/trema/set-vlan-vid_spec.rb +65 -0
  143. data/spec/trema/shell/vhost_spec.rb +4 -1
  144. data/spec/trema/shell/vswitch_spec.rb +11 -11
  145. data/spec/trema/stats-reply_spec.rb +59 -13
  146. data/spec/trema/stats-request_spec.rb +6 -0
  147. data/spec/trema/{action-strip-vlan_spec.rb → strip-vlan-header_spec.rb} +3 -17
  148. data/spec/trema/switch-daemon_spec.rb +39 -0
  149. data/spec/trema/vendor-action_spec.rb +81 -0
  150. data/spec/trema/vendor_spec.rb +76 -0
  151. data/spec/trema_spec.rb +56 -0
  152. data/src/examples/dumper/dumper.c +0 -8
  153. data/src/examples/dumper/dumper.rb +52 -52
  154. data/src/examples/hello_trema/hello_trema.c +0 -2
  155. data/src/examples/learning_switch/learning-switch.rb +3 -3
  156. data/src/examples/multi_learning_switch/multi-learning-switch.rb +3 -3
  157. data/src/examples/openflow_message/features-request.rb +3 -3
  158. data/src/examples/packetin_filter_config/utils.c +4 -4
  159. data/src/examples/repeater_hub/repeater-hub.rb +3 -3
  160. data/src/examples/switch_info/switch_info.rb +2 -2
  161. data/src/examples/switch_monitor/switch_monitor.c +1 -1
  162. data/src/examples/traffic_monitor/traffic-monitor.rb +3 -3
  163. data/src/lib/arp.h +4 -1
  164. data/src/lib/chibach.c +391 -0
  165. data/src/lib/chibach.h +71 -0
  166. data/src/lib/chibach_private.c +170 -0
  167. data/src/lib/chibach_private.h +52 -0
  168. data/src/lib/ether.c +2 -1
  169. data/src/lib/ether.h +0 -1
  170. data/src/lib/ipv4.h +13 -14
  171. data/{ruby/trema/action-set-nw-src.h → src/lib/ipv6.h} +13 -9
  172. data/src/lib/log.c +161 -58
  173. data/src/lib/log.h +11 -16
  174. data/src/lib/messenger.c +36 -1
  175. data/src/lib/messenger.h +1 -0
  176. data/src/lib/openflow_application_interface.c +128 -28
  177. data/src/lib/openflow_application_interface.h +31 -6
  178. data/src/lib/openflow_message.c +2 -1
  179. data/src/lib/openflow_service_interface.h +1 -0
  180. data/src/lib/openflow_switch_interface.c +1380 -0
  181. data/src/lib/openflow_switch_interface.h +264 -0
  182. data/src/lib/packet_info.c +94 -11
  183. data/src/lib/packet_info.h +22 -3
  184. data/src/lib/packet_parser.c +38 -2
  185. data/src/lib/secure_channel.c +498 -0
  186. data/{ruby/trema/vendor-request.h → src/lib/secure_channel.h} +11 -10
  187. data/src/lib/tcp.h +0 -3
  188. data/src/lib/trema.c +38 -5
  189. data/{ruby/trema/action-set-nw-dst.h → src/lib/trema.hpp} +17 -8
  190. data/src/lib/trema_wrapper.c +5 -0
  191. data/src/lib/trema_wrapper.h +4 -0
  192. data/src/lib/utility.c +93 -4
  193. data/src/lib/utility.h +1 -0
  194. data/src/lib/wrapper.c +30 -7
  195. data/src/lib/wrapper.h +2 -0
  196. data/src/switch_manager/ofpmsg_recv.c +44 -30
  197. data/src/switch_manager/ofpmsg_send.c +40 -1
  198. data/src/switch_manager/ofpmsg_send.h +2 -0
  199. data/src/switch_manager/switch.c +153 -8
  200. data/src/switch_manager/switch.h +1 -0
  201. data/src/switch_manager/switchinfo.h +5 -0
  202. data/src/tremashark/README +2 -2
  203. data/src/tremashark/plugin/packet-trema/packet-trema.c +1 -0
  204. data/trema +1 -1
  205. data/unittests/lib/log_test.c +158 -34
  206. data/unittests/lib/openflow_application_interface_test.c +252 -69
  207. data/unittests/lib/openflow_message_test.c +3 -1
  208. data/unittests/lib/packet_parser_test.c +60 -15
  209. data/unittests/lib/test_packets/icmp6_echo_rep.cap +0 -0
  210. data/unittests/lib/test_packets/icmp6_echo_req.cap +0 -0
  211. data/unittests/lib/trema_test.c +2 -0
  212. data/unittests/lib/utility_test.c +65 -2
  213. data/unittests/lib/wrapper_test.c +29 -0
  214. data/vendor/{README → README.md} +2 -12
  215. data/vendor/packet-openflow.diff +13 -0
  216. metadata +86 -53
  217. data/GPL2 +0 -339
  218. data/ruby/trema/action-enqueue.c +0 -161
  219. data/ruby/trema/action-output.c +0 -169
  220. data/ruby/trema/action-set-dl-dst.c +0 -131
  221. data/ruby/trema/action-set-dl-dst.h +0 -44
  222. data/ruby/trema/action-set-dl-src.c +0 -131
  223. data/ruby/trema/action-set-nw-dst.c +0 -135
  224. data/ruby/trema/action-set-nw-src.c +0 -140
  225. data/ruby/trema/action-set-nw-tos.c +0 -124
  226. data/ruby/trema/action-set-nw-tos.h +0 -42
  227. data/ruby/trema/action-set-tp-dst.c +0 -122
  228. data/ruby/trema/action-set-tp-dst.h +0 -42
  229. data/ruby/trema/action-set-tp-src.c +0 -124
  230. data/ruby/trema/action-set-tp-src.h +0 -42
  231. data/ruby/trema/action-set-vlan-pcp.c +0 -128
  232. data/ruby/trema/action-set-vlan-pcp.h +0 -42
  233. data/ruby/trema/action-set-vlan-vid.c +0 -125
  234. data/ruby/trema/action-set-vlan-vid.h +0 -42
  235. data/ruby/trema/action-strip-vlan.c +0 -81
  236. data/ruby/trema/action-strip-vlan.h +0 -42
  237. data/ruby/trema/action-vendor.c +0 -121
  238. data/ruby/trema/vendor-request.c +0 -193
  239. data/spec/trema/action-enqueue_spec.rb +0 -100
  240. data/spec/trema/action-set-dl-dst_spec.rb +0 -95
  241. data/spec/trema/action-set-dl-src_spec.rb +0 -92
  242. data/spec/trema/action-set-nw-dst_spec.rb +0 -96
  243. data/spec/trema/action-set-nw-src_spec.rb +0 -97
  244. data/spec/trema/action-set-nw-tos_spec.rb +0 -88
  245. data/spec/trema/action-set-tp-dst_spec.rb +0 -88
  246. data/spec/trema/action-set-tp-src_spec.rb +0 -88
  247. data/spec/trema/action-set-vlan-pcp_spec.rb +0 -91
  248. data/spec/trema/action-set-vlan-vid_spec.rb +0 -91
  249. data/spec/trema/action-vendor_spec.rb +0 -90
  250. data/spec/trema/vendor-request_spec.rb +0 -79
data/ruby/extconf.rb CHANGED
@@ -45,6 +45,10 @@ EOF
45
45
  end
46
46
 
47
47
 
48
+ unless find_library( "pthread", "pthread_create" )
49
+ error_exit error_lib_missing( "libpthread", "libc6-dev" )
50
+ end
51
+
48
52
  unless find_library( "rt", "clock_gettime" )
49
53
  error_exit error_lib_missing( "librt", "libc6-dev" )
50
54
  end
@@ -68,4 +72,3 @@ end
68
72
 
69
73
 
70
74
  create_makefile "trema", "trema"
71
-
@@ -1,6 +1,4 @@
1
1
  /*
2
- * Author: Nick Karanatsios <nickkaranatsios@gmail.com>
3
- *
4
2
  * Copyright (C) 2008-2012 NEC Corporation
5
3
  *
6
4
  * This program is free software; you can redistribute it and/or modify
@@ -22,30 +20,18 @@
22
20
  #include "ruby.h"
23
21
 
24
22
 
25
- /*
26
- * @return [Number] an IPv4 address in its numeric representation.
27
- */
28
23
  uint32_t
29
24
  nw_addr_to_i( VALUE nw_addr ) {
30
25
  return ( uint32_t ) NUM2UINT( rb_funcall( nw_addr, rb_intern( "to_i" ), 0 ) );
31
26
  }
32
27
 
33
28
 
34
- /*
35
- * @return [String] an IPv4 address in its text representation.
36
- */
37
- VALUE
38
- nw_addr_to_s( VALUE nw_addr ) {
39
- return rb_funcall( nw_addr, rb_intern( "to_s" ), 0 );
40
- }
41
-
42
-
43
29
  uint8_t *
44
- dl_addr_short( VALUE dl_addr, uint8_t *ret_dl_addr ) {
45
- VALUE mac_arr = rb_funcall( dl_addr, rb_intern( "to_short" ), 0 );
30
+ dl_addr_to_a( VALUE dl_addr, uint8_t *ret_dl_addr ) {
31
+ VALUE mac_arr = rb_funcall( dl_addr, rb_intern( "to_a" ), 0 );
46
32
  int i;
47
33
 
48
- for ( i = 0; i < RARRAY_LEN( mac_arr); i++ ) {
34
+ for ( i = 0; i < RARRAY_LEN( mac_arr ); i++ ) {
49
35
  ret_dl_addr[ i ] = ( uint8_t ) ( NUM2INT( RARRAY_PTR( mac_arr )[ i ] ) );
50
36
  }
51
37
  return ret_dl_addr;
@@ -1,6 +1,4 @@
1
1
  /*
2
- * Author: Nick Karanatsios <nickkaranatsios@gmail.com>
3
- *
4
2
  * Copyright (C) 2008-2012 NEC Corporation
5
3
  *
6
4
  * This program is free software; you can redistribute it and/or modify
@@ -22,13 +20,11 @@
22
20
  #define ACTION_COMMON_H
23
21
 
24
22
 
25
- uint32_t nw_addr_to_i( VALUE nw_addr );
26
-
23
+ #include <stdint.h>
27
24
 
28
- VALUE nw_addr_to_s( VALUE nw_addr );
29
25
 
30
-
31
- uint8_t *dl_addr_short( VALUE dl_addr, uint8_t *ret_dl_addr );
26
+ uint32_t nw_addr_to_i( VALUE nw_addr );
27
+ uint8_t *dl_addr_to_a( VALUE dl_addr, uint8_t *ret_dl_addr );
32
28
 
33
29
 
34
30
  #endif // ACTION_COMMON_H
@@ -0,0 +1,33 @@
1
+ #
2
+ # Copyright (C) 2008-2012 NEC Corporation
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License, version 2, as
6
+ # published by the Free Software Foundation.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License along
14
+ # with this program; if not, write to the Free Software Foundation, Inc.,
15
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
+ #
17
+
18
+
19
+ module Trema
20
+ #
21
+ # A base action class just for defining a meta-type for all action
22
+ # classes.
23
+ #
24
+ class Action
25
+ end
26
+ end
27
+
28
+
29
+ ### Local variables:
30
+ ### mode: Ruby
31
+ ### coding: utf-8-unix
32
+ ### indent-tabs-mode: nil
33
+ ### End:
data/ruby/trema/app.rb CHANGED
@@ -37,7 +37,7 @@ module Trema
37
37
 
38
38
 
39
39
  #
40
- # Creates a new Trema application from {DSL::App}
40
+ # Creates a new Trema application from {Trema::DSL::App}
41
41
  #
42
42
  # @example
43
43
  # app = Trema::App.new( stanza )
@@ -97,6 +97,7 @@ Init_barrier_request() {
97
97
  rb_define_alloc_func( cBarrierRequest, barrier_request_alloc );
98
98
  rb_define_method( cBarrierRequest, "initialize", barrier_request_init, -1 );
99
99
  rb_define_method( cBarrierRequest, "transaction_id", barrier_request_transaction_id, 0 );
100
+ rb_alias( cBarrierRequest, rb_intern( "xid" ), rb_intern( "transaction_id" ) );
100
101
  }
101
102
 
102
103
 
@@ -42,6 +42,9 @@ module Trema
42
42
  options.on( "-d", "--daemonize" ) do
43
43
  $run_as_daemon = true
44
44
  end
45
+ options.on( "-s", "--tremashark" ) do
46
+ $use_tremashark = true
47
+ end
45
48
 
46
49
  options.separator ""
47
50
 
@@ -88,17 +91,18 @@ module Trema
88
91
 
89
92
  if ARGV[ 0 ]
90
93
  controller_file = ARGV[ 0 ].split.first
91
- if c_controller?
94
+ if ruby_controller?
95
+ require "trema"
96
+ include Trema
97
+ ARGV.replace ARGV[ 0 ].split
98
+ $LOAD_PATH << File.dirname( controller_file )
99
+ load controller_file
100
+ else
101
+ # Assume that the controller is written in C
92
102
  stanza = Trema::DSL::Run.new
93
103
  stanza.path controller_file
94
104
  stanza.options ARGV[ 0 ].split[ 1..-1 ]
95
105
  Trema::App.new( stanza )
96
- else
97
- # Ruby controller
98
- require "trema"
99
- ARGV.replace ARGV[ 0 ].split
100
- $LOAD_PATH << File.dirname( controller_file )
101
- Trema.module_eval IO.read( controller_file )
102
106
  end
103
107
  end
104
108
 
@@ -106,8 +110,8 @@ module Trema
106
110
  end
107
111
 
108
112
 
109
- def c_controller?
110
- /ELF/=~ `file #{ ARGV[ 0 ].split.first }`
113
+ def ruby_controller?
114
+ /\.rb\Z/=~ ARGV[ 0 ].split.first
111
115
  end
112
116
  end
113
117
  end
@@ -43,6 +43,7 @@ Available commands:
43
43
  reset_stats - resets stats of packets.
44
44
  dump_flows - print all flow entries.
45
45
  ruby - opens in your browser Trema's Ruby API documentation.
46
+ version - displays the current runtime version.
46
47
  EOL
47
48
  elsif method_for( command )
48
49
  __send__ method_for( command )
@@ -25,7 +25,7 @@ require "trema/version"
25
25
 
26
26
  module Trema
27
27
  module Command
28
- def version
28
+ def show_version
29
29
  puts "trema version #{ Trema::VERSION }"
30
30
  end
31
31
  end
@@ -1,6 +1,4 @@
1
1
  /*
2
- * Author: Yasuhito Takamiya <yasuhito@gmail.com>
3
- *
4
2
  * Copyright (C) 2008-2012 NEC Corporation
5
3
  *
6
4
  * This program is free software; you can redistribute it and/or modify
@@ -18,6 +16,8 @@
18
16
  */
19
17
 
20
18
 
19
+ #include "ruby.h"
20
+ #include "action-common.h"
21
21
  #include "barrier-reply.h"
22
22
  #include "buffer.h"
23
23
  #include "controller.h"
@@ -28,10 +28,9 @@
28
28
  #include "logger.h"
29
29
  #include "openflow-error.h"
30
30
  #include "openflow.h"
31
- #include "packet_in.h"
31
+ #include "packet-in.h"
32
32
  #include "port-status.h"
33
33
  #include "queue-get-config-reply.h"
34
- #include "ruby.h"
35
34
  #include "rubysig.h"
36
35
  #include "stats-reply.h"
37
36
  #include "switch-disconnected.h"
@@ -39,7 +38,7 @@
39
38
  #include "vendor.h"
40
39
 
41
40
 
42
- VALUE mTrema;
41
+ extern VALUE mTrema;
43
42
  VALUE cController;
44
43
 
45
44
 
@@ -82,22 +81,90 @@ controller_send_list_switches_request( VALUE self ) {
82
81
 
83
82
 
84
83
  static void
85
- form_actions( VALUE raction, openflow_actions *actions ) {
86
- VALUE *data_ptr;
87
- int i;
84
+ append_action( openflow_actions *actions, VALUE action ) {
85
+ if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::Enqueue" ) ) == Qtrue ) {
86
+ uint32_t queue_id = ( uint32_t ) NUM2UINT( rb_funcall( action, rb_intern( "queue_id" ), 0 ) );
87
+ uint16_t port_number = ( uint16_t ) NUM2UINT( rb_funcall( action, rb_intern( "port_number" ), 0 ) );
88
+ append_action_enqueue( actions, port_number, queue_id );
89
+ }
90
+ else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SendOutPort" ) ) == Qtrue ) {
91
+ uint16_t port_number = ( uint16_t ) NUM2UINT( rb_funcall( action, rb_intern( "port_number" ), 0 ) );
92
+ uint16_t max_len = ( uint16_t ) NUM2UINT( rb_funcall( action, rb_intern( "max_len" ), 0 ) );
93
+ append_action_output( actions, port_number, max_len );
94
+ }
95
+ else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetEthDstAddr" ) ) == Qtrue ) {
96
+ uint8_t dl_dst[ OFP_ETH_ALEN ];
97
+ uint8_t *ptr = ( uint8_t* ) dl_addr_to_a( rb_funcall( action, rb_intern( "mac_address" ), 0 ), dl_dst );
98
+ append_action_set_dl_dst( actions, ptr );
99
+ }
100
+ else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetEthSrcAddr" ) ) == Qtrue ) {
101
+ uint8_t dl_src[ OFP_ETH_ALEN ];
102
+ uint8_t *ptr = ( uint8_t* ) dl_addr_to_a( rb_funcall( action, rb_intern( "mac_address" ), 0 ), dl_src );
103
+ append_action_set_dl_src( actions, ptr );
104
+ }
105
+ else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetIpDstAddr" ) ) == Qtrue ) {
106
+ append_action_set_nw_dst( actions, nw_addr_to_i( rb_funcall( action, rb_intern( "ip_address" ), 0 ) ) );
107
+ }
108
+ else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetIpSrcAddr" ) ) == Qtrue ) {
109
+ append_action_set_nw_src( actions, nw_addr_to_i( rb_funcall( action, rb_intern( "ip_address" ), 0 ) ) );
110
+ }
111
+ else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetIpTos" ) ) == Qtrue ) {
112
+ append_action_set_nw_tos( actions, ( uint8_t ) NUM2UINT( rb_funcall( action, rb_intern( "type_of_service" ), 0 ) ) );
113
+ }
114
+ else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetTransportDstPort" ) ) == Qtrue ) {
115
+ append_action_set_tp_dst( actions, ( uint16_t ) NUM2UINT( rb_funcall( action, rb_intern( "port_number" ), 0 ) ) );
116
+ }
117
+ else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetTransportSrcPort" ) ) == Qtrue ) {
118
+ append_action_set_tp_src( actions, ( uint16_t ) NUM2UINT( rb_funcall( action, rb_intern( "port_number" ), 0 ) ) );
119
+ }
120
+ else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetVlanPriority" ) ) == Qtrue ) {
121
+ append_action_set_vlan_pcp( actions, ( uint8_t ) NUM2UINT( rb_funcall( action, rb_intern( "vlan_priority" ), 0 ) ) );
122
+ }
123
+ else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetVlanVid" ) ) == Qtrue ) {
124
+ append_action_set_vlan_vid( actions, ( uint16_t ) NUM2UINT( rb_funcall( action, rb_intern( "vlan_id" ), 0 ) ) );
125
+ }
126
+ else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::StripVlanHeader" ) ) == Qtrue ) {
127
+ append_action_strip_vlan( actions );
128
+ }
129
+ else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::VendorAction" ) ) == Qtrue ) {
130
+ VALUE vendor_id = rb_funcall( action, rb_intern( "vendor_id" ), 0 );
131
+ VALUE rbody = rb_funcall( action, rb_intern( "body" ), 0 );
132
+ if ( rbody != Qnil ) {
133
+ Check_Type( rbody, T_ARRAY );
134
+ uint16_t length = ( uint16_t ) RARRAY_LEN( rbody );
135
+ buffer *body = alloc_buffer_with_length( length );
136
+ int i;
137
+ for ( i = 0; i < length; i++ ) {
138
+ ( ( uint8_t * ) body->data )[ i ] = ( uint8_t ) FIX2INT( RARRAY_PTR( rbody )[ i ] );
139
+ }
140
+ append_action_vendor( actions, ( uint32_t ) NUM2UINT( vendor_id ), body );
141
+ free_buffer( body );
142
+ }
143
+ else {
144
+ append_action_vendor( actions, ( uint32_t ) NUM2UINT( vendor_id ), NULL );
145
+ }
146
+ }
147
+ else {
148
+ rb_raise( rb_eTypeError, "actions argument must be an Array of Action objects" );
149
+ }
150
+ }
151
+
88
152
 
153
+ static void
154
+ form_actions( VALUE raction, openflow_actions *actions ) {
89
155
  if ( raction != Qnil ) {
90
156
  switch ( TYPE( raction ) ) {
91
157
  case T_ARRAY:
92
- data_ptr = RARRAY_PTR( raction );
93
-
94
- for ( i = 0; i < RARRAY_LEN( raction ); i++ ) {
95
- VALUE value = data_ptr[i];
96
- rb_funcall( value, rb_intern( "append" ), 1, Data_Wrap_Struct( cController, NULL, NULL, actions ) );
158
+ {
159
+ VALUE *each = RARRAY_PTR( raction );
160
+ int i;
161
+ for ( i = 0; i < RARRAY_LEN( raction ); i++ ) {
162
+ append_action( actions, each[ i ] );
163
+ }
97
164
  }
98
165
  break;
99
166
  case T_OBJECT:
100
- rb_funcall( raction, rb_intern( "append" ), 1, Data_Wrap_Struct( cController, NULL, NULL, actions ) );
167
+ append_action( actions, raction );
101
168
  break;
102
169
  default:
103
170
  rb_raise( rb_eTypeError, "actions argument must be an Array or an Action object" );
@@ -136,6 +203,7 @@ controller_send_flow_mod( uint16_t command, int argc, VALUE *argv, VALUE self )
136
203
  uint16_t hard_timeout = 0;
137
204
  uint16_t priority = UINT16_MAX;
138
205
  uint32_t buffer_id = UINT32_MAX;
206
+ uint16_t out_port = OFPP_NONE;
139
207
  uint16_t flags = OFPFF_SEND_FLOW_REM;
140
208
  openflow_actions *actions = create_actions();
141
209
 
@@ -171,6 +239,11 @@ controller_send_flow_mod( uint16_t command, int argc, VALUE *argv, VALUE self )
171
239
  buffer_id = ( uint32_t ) NUM2ULONG( opt_buffer_id );
172
240
  }
173
241
 
242
+ VALUE opt_out_port = rb_hash_aref( options, ID2SYM( rb_intern( "out_port" ) ) );
243
+ if ( opt_out_port != Qnil ) {
244
+ out_port = ( uint16_t )NUM2UINT( opt_out_port );
245
+ }
246
+
174
247
  VALUE opt_send_flow_rem = rb_hash_aref( options, ID2SYM( rb_intern( "send_flow_rem" ) ) );
175
248
  if ( opt_send_flow_rem == Qfalse ) {
176
249
  flags &= ( uint16_t ) ~OFPFF_SEND_FLOW_REM;
@@ -201,7 +274,7 @@ controller_send_flow_mod( uint16_t command, int argc, VALUE *argv, VALUE self )
201
274
  hard_timeout,
202
275
  priority,
203
276
  buffer_id,
204
- OFPP_NONE,
277
+ out_port,
205
278
  flags,
206
279
  actions
207
280
  );
@@ -220,7 +293,7 @@ controller_send_flow_mod( uint16_t command, int argc, VALUE *argv, VALUE self )
220
293
  *
221
294
  * @example
222
295
  * def packet_in datapath_id, message
223
- * send_flow_mod_add datapath_id, :match => Match.from(message), :actions => ActionOutput.new(OFPP_FLOOD)
296
+ * send_flow_mod_add datapath_id, :match => Match.from(message), :actions => SendOutPort.new(OFPP_FLOOD)
224
297
  * end
225
298
  *
226
299
  *
@@ -253,6 +326,10 @@ controller_send_flow_mod( uint16_t command, int argc, VALUE *argv, VALUE self )
253
326
  * apply the flow to. If 0xffffffff, no buffered packet is to be
254
327
  * applied to flow actions.
255
328
  *
329
+ * @option options [Number] :out_port (0xffff)
330
+ * If the option contains a value other than OFPP_NONE(0xffff),
331
+ * it introduces a constraint when deleting flow entries.
332
+ *
256
333
  * @option options [Boolean] :send_flow_rem (true)
257
334
  * If true, send a flow_removed message when the flow expires or
258
335
  * is deleted.
@@ -263,11 +340,11 @@ controller_send_flow_mod( uint16_t command, int argc, VALUE *argv, VALUE self )
263
340
  * added and the modification fails.
264
341
  *
265
342
  * @option options [Boolean] :emerg (false)
266
- * if true, the switch must consider this flow entry as an
343
+ * If true, the switch must consider this flow entry as an
267
344
  * emergency entry, and only use it for forwarding when
268
345
  * disconnected from the controller.
269
346
  *
270
- * @option options [ActionOutput, Array<ActionOutput>, nil] :actions (nil)
347
+ * @option options [SendOutPort, Array<SendOutPort>, nil] :actions (nil)
271
348
  * The sequence of actions specifying the actions to perform on
272
349
  * the flow's packets.
273
350
  */
@@ -331,7 +408,7 @@ controller_send_flow_mod_delete( int argc, VALUE *argv, VALUE self ) {
331
408
  * send_packet_out(
332
409
  * datapath_id,
333
410
  * :packet_in => message,
334
- * :actions => Trema::ActionOutput.new(port_no)
411
+ * :actions => Trema::SendOutPort.new(port_no)
335
412
  * )
336
413
  *
337
414
  *
@@ -361,9 +438,12 @@ controller_send_flow_mod_delete( int argc, VALUE *argv, VALUE self ) {
361
438
  * The entire Ethernet frame. Should be of length 0 if buffer_id
362
439
  * is 0xffffffff, and should be of length >0 otherwise.
363
440
  *
364
- * @option options [ActionOutput, Array<ActionOutput>, nil] :actions (nil)
441
+ * @option options [Action, Array<Action>, nil] :actions (nil)
365
442
  * The sequence of actions specifying the actions to perform on
366
443
  * the frame.
444
+ *
445
+ * @option options [Boolean] :zero_padding (false)
446
+ * If true, fill up to minimum ethernet frame size.
367
447
  */
368
448
  static VALUE
369
449
  controller_send_packet_out( int argc, VALUE *argv, VALUE self ) {
@@ -377,6 +457,7 @@ controller_send_packet_out( int argc, VALUE *argv, VALUE self ) {
377
457
  openflow_actions *actions = create_actions();
378
458
  const buffer *data = NULL;
379
459
  buffer *allocated_data = NULL;
460
+ VALUE opt_zero_padding = Qnil;
380
461
 
381
462
  if ( options != Qnil ) {
382
463
  VALUE opt_message = rb_hash_aref( options, ID2SYM( rb_intern( "packet_in" ) ) );
@@ -414,6 +495,22 @@ controller_send_packet_out( int argc, VALUE *argv, VALUE self ) {
414
495
  memcpy( append_back_buffer( allocated_data, length ), RSTRING_PTR( opt_data ), length );
415
496
  data = allocated_data;
416
497
  }
498
+
499
+ opt_zero_padding = rb_hash_aref( options, ID2SYM( rb_intern( "zero_padding" ) ) );
500
+ if ( opt_zero_padding != Qnil ) {
501
+ if ( TYPE( opt_zero_padding ) != T_TRUE && TYPE( opt_zero_padding ) != T_FALSE) {
502
+ rb_raise(rb_eTypeError, ":zero_padding must be true or false");
503
+ }
504
+ }
505
+ }
506
+
507
+ if ( data != NULL && data->length + ETH_FCS_LENGTH < ETH_MINIMUM_LENGTH &&
508
+ opt_zero_padding != Qnil && TYPE( opt_zero_padding ) == T_TRUE ) {
509
+ if ( allocated_data == NULL ) {
510
+ allocated_data = duplicate_buffer( data );
511
+ data = allocated_data;
512
+ }
513
+ fill_ether_padding( allocated_data );
417
514
  }
418
515
 
419
516
  buffer *packet_out = create_packet_out(
@@ -522,16 +619,31 @@ controller_start_trema( VALUE self ) {
522
619
  return self;
523
620
  }
524
621
 
622
+
525
623
  /********************************************************************************
526
624
  * Init Controller module.
527
625
  ********************************************************************************/
528
626
 
529
627
  void
530
628
  Init_controller() {
629
+ rb_require( "trema/enqueue" );
630
+ rb_require( "trema/send-out-port" );
631
+ rb_require( "trema/set-eth-dst-addr" );
632
+ rb_require( "trema/set-eth-src-addr" );
633
+ rb_require( "trema/set-ip-dst-addr" );
634
+ rb_require( "trema/set-ip-src-addr" );
635
+ rb_require( "trema/set-ip-tos" );
636
+ rb_require( "trema/set-transport-dst-port" );
637
+ rb_require( "trema/set-transport-src-port" );
638
+ rb_require( "trema/set-vlan-priority" );
639
+ rb_require( "trema/set-vlan-vid" );
640
+ rb_require( "trema/strip-vlan-header" );
641
+ rb_require( "trema/vendor-action" );
642
+
531
643
  rb_require( "trema/app" );
644
+
532
645
  VALUE cApp = rb_eval_string( "Trema::App" );
533
646
  cController = rb_define_class_under( mTrema, "Controller", cApp );
534
- rb_include_module( cController, mLogger );
535
647
 
536
648
  rb_define_const( cController, "OFPP_MAX", INT2NUM( OFPP_MAX ) );
537
649
  rb_define_const( cController, "OFPP_IN_PORT", INT2NUM( OFPP_IN_PORT ) );
@@ -543,33 +655,6 @@ Init_controller() {
543
655
  rb_define_const( cController, "OFPP_LOCAL", INT2NUM( OFPP_LOCAL ) );
544
656
  rb_define_const( cController, "OFPP_NONE", INT2NUM( OFPP_NONE ) );
545
657
 
546
- rb_define_const( cController, "OFPPR_ADD", INT2NUM( OFPPR_ADD ) );
547
- rb_define_const( cController, "OFPPR_DELETE", INT2NUM( OFPPR_DELETE ) );
548
- rb_define_const( cController, "OFPPR_MODIFY", INT2NUM( OFPPR_MODIFY ) );
549
-
550
- rb_define_const( cController, "OFPC_FLOW_STATS", INT2NUM( OFPC_FLOW_STATS ) );
551
- rb_define_const( cController, "OFPC_TABLE_STATS", INT2NUM( OFPC_TABLE_STATS ) );
552
- rb_define_const( cController, "OFPC_PORT_STATS", INT2NUM( OFPC_PORT_STATS ) );
553
- rb_define_const( cController, "OFPC_STP", INT2NUM( OFPC_STP) );
554
- rb_define_const( cController, "OFPC_RESERVED", INT2NUM( OFPC_RESERVED ) );
555
- rb_define_const( cController, "OFPC_IP_REASM", INT2NUM( OFPC_IP_REASM ) );
556
- rb_define_const( cController, "OFPC_QUEUE_STATS", INT2NUM( OFPC_QUEUE_STATS ) );
557
- rb_define_const( cController, "OFPC_ARP_MATCH_IP", INT2NUM( OFPC_ARP_MATCH_IP ) );
558
-
559
- rb_define_const( cController, "OFPAT_OUTPUT", INT2NUM( OFPAT_OUTPUT ) );
560
- rb_define_const( cController, "OFPAT_SET_VLAN_VID", INT2NUM( OFPAT_SET_VLAN_VID ) );
561
- rb_define_const( cController, "OFPAT_SET_VLAN_PCP", INT2NUM( OFPAT_SET_VLAN_PCP ) );
562
- rb_define_const( cController, "OFPAT_STRIP_VLAN", INT2NUM( OFPAT_STRIP_VLAN ) );
563
- rb_define_const( cController, "OFPAT_SET_DL_SRC", INT2NUM( OFPAT_SET_DL_SRC) );
564
- rb_define_const( cController, "OFPAT_SET_DL_DST", INT2NUM( OFPAT_SET_DL_DST) );
565
- rb_define_const( cController, "OFPAT_SET_NW_SRC", INT2NUM( OFPAT_SET_NW_SRC ) );
566
- rb_define_const( cController, "OFPAT_SET_NW_DST", INT2NUM( OFPAT_SET_NW_DST ) );
567
- rb_define_const( cController, "OFPAT_SET_NW_TOS", INT2NUM( OFPAT_SET_NW_TOS ) );
568
- rb_define_const( cController, "OFPAT_SET_TP_SRC", INT2NUM( OFPAT_SET_TP_SRC ) );
569
- rb_define_const( cController, "OFPAT_SET_TP_DST", INT2NUM( OFPAT_SET_TP_DST ) );
570
- rb_define_const( cController, "OFPAT_ENQUEUE", INT2NUM( OFPAT_ENQUEUE ) );
571
- rb_define_const( cController, "OFPAT_VENDOR", INT2NUM( OFPAT_VENDOR ) );
572
-
573
658
  rb_define_method( cController, "send_message", controller_send_message, 2 );
574
659
  rb_define_method( cController, "send_list_switches_request", controller_send_list_switches_request, 0 );
575
660
  rb_define_method( cController, "send_flow_mod_add", controller_send_flow_mod_add, -1 );
@@ -579,8 +664,6 @@ Init_controller() {
579
664
 
580
665
  rb_define_method( cController, "run!", controller_run, 0 );
581
666
  rb_define_method( cController, "shutdown!", controller_shutdown, 0 );
582
-
583
- // Private
584
667
  rb_define_private_method( cController, "start_trema", controller_start_trema, 0 );
585
668
 
586
669
  rb_require( "trema/controller" );