trema 0.2.2.1 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -130,36 +130,38 @@ ofpmsg_recv_error( struct switch_info *sw_info, buffer *buf ) {
130
130
  free_buffer( buf );
131
131
  return 0;
132
132
  }
133
- cookie_entry_t *entry = lookup_cookie_entry_by_cookie( &cookie );
134
- if ( entry != NULL ) {
135
- flow_mod->cookie = htonll( entry->application.cookie );
136
- if ( length >= offsetof( struct ofp_flow_mod, actions ) ) {
137
- flow_mod->flags = htons( entry->application.flags );
138
- }
139
- }
140
-
141
- if ( length >= offsetof( struct ofp_flow_mod, idle_timeout ) ) {
142
- uint16_t command = ntohs( flow_mod->command );
143
- switch ( command ) {
144
- case OFPFC_ADD:
145
- {
146
- if ( entry != NULL ) {
147
- delete_cookie_entry( entry );
148
- }
149
- else {
150
- error( "No cookie entry found ( cookie = %#" PRIx64 " ).", cookie );
133
+ if ( sw_info->cookie_translation ) {
134
+ cookie_entry_t *entry = lookup_cookie_entry_by_cookie( &cookie );
135
+ if ( entry != NULL ) {
136
+ flow_mod->cookie = htonll( entry->application.cookie );
137
+ if ( length >= offsetof( struct ofp_flow_mod, actions ) ) {
138
+ flow_mod->flags = htons( entry->application.flags );
151
139
  }
152
140
  }
153
- break;
154
141
 
155
- case OFPFC_MODIFY:
156
- case OFPFC_MODIFY_STRICT:
157
- case OFPFC_DELETE:
158
- case OFPFC_DELETE_STRICT:
142
+ if ( length >= offsetof( struct ofp_flow_mod, idle_timeout ) ) {
143
+ uint16_t command = ntohs( flow_mod->command );
144
+ switch ( command ) {
145
+ case OFPFC_ADD:
146
+ {
147
+ if ( entry != NULL ) {
148
+ delete_cookie_entry( entry );
149
+ }
150
+ else {
151
+ error( "No cookie entry found ( cookie = %#" PRIx64 " ).", cookie );
152
+ }
153
+ }
159
154
  break;
160
155
 
161
- default:
162
- error( "Undefined flow_mod command ( command = %#x ).", command );
156
+ case OFPFC_MODIFY:
157
+ case OFPFC_MODIFY_STRICT:
158
+ case OFPFC_DELETE:
159
+ case OFPFC_DELETE_STRICT:
160
+ break;
161
+
162
+ default:
163
+ error( "Undefined flow_mod command ( command = %#x ).", command );
164
+ }
163
165
  }
164
166
  }
165
167
  }
@@ -190,9 +192,13 @@ int
190
192
  ofpmsg_recv_echoreply( struct switch_info *sw_info, buffer *buf ) {
191
193
  ofpmsg_debug( "Receive 'echo reply' from a switch." );
192
194
 
193
- // TODO: implement keepalive mechanism
195
+ int ret = switch_event_recv_echoreply( sw_info, buf );
196
+ if ( ret < 0 ) {
197
+ free_buffer( buf );
198
+ return ret;
199
+ }
194
200
 
195
- free_buffer( buf );
201
+ send_transaction_reply( sw_info, buf );
196
202
 
197
203
  return 0;
198
204
  }
@@ -274,14 +280,22 @@ ofpmsg_recv_flowremoved( struct switch_info *sw_info, buffer *buf ) {
274
280
  return 0;
275
281
  }
276
282
 
283
+ if ( !sw_info->cookie_translation ) {
284
+ service_send_to_application( sw_info->state_service_name_list, MESSENGER_OPENFLOW_MESSAGE,
285
+ &sw_info->datapath_id, buf );
286
+ free_buffer( buf );
287
+ return 0;
288
+ }
289
+
277
290
  entry = lookup_cookie_entry_by_cookie( &cookie );
278
291
  if ( entry == NULL ) {
279
292
  error( "No cookie entry found ( cookie = %#" PRIx64 " ).", cookie );
280
293
  free_buffer( buf );
281
294
  return 0;
282
295
  }
283
- debug( "Cookie found ( cookie = %#" PRIx64 ", application = [ cookie = %#" PRIx64 ", service name = %s, flags = %#x ], "
284
- "reference_count = %d, expire_at = %u ).",
296
+
297
+ debug( "Cookie found ( cookie = %#" PRIx64 ", application = [ cookie = %#" PRIx64
298
+ ", service name = %s, flags = %#x ], reference_count = %d, expire_at = %u ).",
285
299
  cookie, entry->application.cookie, entry->application.service_name, entry->application.flags,
286
300
  entry->reference_count, entry->expire_at );
287
301
 
@@ -319,7 +333,7 @@ ofpmsg_recv_statsreply( struct switch_info *sw_info, buffer *buf ) {
319
333
 
320
334
  ofpmsg_debug( "Receive 'statistics reply' from a switch." );
321
335
 
322
- if ( type == OFPST_FLOW ) {
336
+ if ( type == OFPST_FLOW && sw_info->cookie_translation ) {
323
337
  size_t body_offset = offsetof( struct ofp_stats_reply, body );
324
338
  int body_length = ntohs( stats_reply->header.length ) - ( int ) body_offset;
325
339
  struct ofp_flow_stats *flow_stats = ( void * ) ( ( char * ) stats_reply + body_offset );
@@ -46,6 +46,23 @@ ofpmsg_send_hello( struct switch_info *sw_info ) {
46
46
  }
47
47
 
48
48
 
49
+ int
50
+ ofpmsg_send_echorequest( struct switch_info *sw_info, uint32_t xid, buffer *body ) {
51
+ int ret;
52
+ buffer *buf;
53
+
54
+ buf = create_echo_request( xid, body );
55
+ free_buffer( body );
56
+
57
+ ret = send_to_secure_channel( sw_info, buf );
58
+ if ( ret == 0 ) {
59
+ debug( "Send 'echo request' to a switch %#" PRIx64 ".", sw_info->datapath_id );
60
+ }
61
+
62
+ return ret;
63
+ }
64
+
65
+
49
66
  int
50
67
  ofpmsg_send_echoreply( struct switch_info *sw_info, uint32_t xid, buffer *body ) {
51
68
  int ret;
@@ -187,7 +204,7 @@ ofpmsg_send( struct switch_info *sw_info, buffer *buf, char *service_name ) {
187
204
  new_xid = insert_xid_entry( ntohl( ofp_header->xid ), service_name );
188
205
  ofp_header->xid = htonl( new_xid );
189
206
 
190
- if ( ofp_header->type == OFPT_FLOW_MOD ) {
207
+ if ( ofp_header->type == OFPT_FLOW_MOD && sw_info->cookie_translation ) {
191
208
  ret = update_flowmod_cookie( buf, service_name );
192
209
  if ( ret < 0 ) {
193
210
  error( "Failed to update cookie value ( ret = %d ).", ret );
@@ -227,6 +244,28 @@ ofpmsg_send_delete_all_flows( struct switch_info *sw_info ) {
227
244
  }
228
245
 
229
246
 
247
+ int
248
+ ofpmsg_send_deny_all( struct switch_info *sw_info ) {
249
+ int ret;
250
+ struct ofp_match match;
251
+ buffer *buf;
252
+
253
+ memset( &match, 0, sizeof( match ) );
254
+ match.wildcards = OFPFW_ALL;
255
+ const uint16_t timeout = 10;
256
+
257
+ buf = create_flow_mod( generate_xid(), match, RESERVED_COOKIE,
258
+ OFPFC_ADD, 0, timeout, UINT16_MAX, UINT32_MAX, OFPP_NONE, 0, NULL );
259
+
260
+ ret = send_to_secure_channel( sw_info, buf );
261
+ if ( ret == 0 ) {
262
+ debug( "Send 'flow mod (deny all)' to a switch %#" PRIx64 ".", sw_info->datapath_id );
263
+ }
264
+
265
+ return ret;
266
+ }
267
+
268
+
230
269
  /*
231
270
  * Local variables:
232
271
  * c-basic-offset: 2
@@ -30,12 +30,14 @@
30
30
 
31
31
 
32
32
  int ofpmsg_send_hello( struct switch_info *sw_info );
33
+ int ofpmsg_send_echorequest( struct switch_info *sw_info, uint32_t xid, buffer *body );
33
34
  int ofpmsg_send_echoreply( struct switch_info *sw_info, uint32_t xid, buffer *body );
34
35
  int ofpmsg_send_featuresrequest( struct switch_info *sw_info );
35
36
  int ofpmsg_send_setconfig( struct switch_info *sw_info );
36
37
  int ofpmsg_send_error_msg( struct switch_info *sw_info, uint16_t type, uint16_t code, buffer *data );
37
38
  int ofpmsg_send( struct switch_info *sw_info, buffer *buf, char *service_name );
38
39
  int ofpmsg_send_delete_all_flows( struct switch_info *sw_info );
40
+ int ofpmsg_send_deny_all( struct switch_info *sw_info );
39
41
 
40
42
 
41
43
  #endif // OFPMSG_SEND_H
@@ -42,13 +42,29 @@
42
42
  #include "xid_table.h"
43
43
 
44
44
 
45
+ #define SUB_TIMESPEC( _a, _b, _return ) \
46
+ do { \
47
+ ( _return )->tv_sec = ( _a )->tv_sec - ( _b )->tv_sec; \
48
+ ( _return )->tv_nsec = ( _a )->tv_nsec - ( _b )->tv_nsec; \
49
+ if ( ( _return )->tv_nsec < 0 ) { \
50
+ ( _return )->tv_sec--; \
51
+ ( _return )->tv_nsec += 1000000000; \
52
+ } \
53
+ } \
54
+ while ( 0 )
55
+
56
+
45
57
  enum long_options_val {
46
58
  NO_FLOW_CLEANUP_LONG_OPTION_VALUE = 1,
59
+ NO_COOKIE_TRANSLATION_LONG_OPTION_VALUE = 2,
60
+ NO_PACKET_IN_LONG_OPTION_VALUE = 3,
47
61
  };
48
62
 
49
63
  static struct option long_options[] = {
50
64
  { "socket", 1, NULL, 's' },
51
65
  { "no-flow-cleanup", 0, NULL, NO_FLOW_CLEANUP_LONG_OPTION_VALUE },
66
+ { "no-cookie-translation", 0, NULL, NO_COOKIE_TRANSLATION_LONG_OPTION_VALUE },
67
+ { "no-packet_in", 0, NULL, NO_PACKET_IN_LONG_OPTION_VALUE },
52
68
  { NULL, 0, NULL, 0 },
53
69
  };
54
70
 
@@ -58,9 +74,16 @@ static char short_options[] = "s:";
58
74
  struct switch_info switch_info;
59
75
 
60
76
  static const time_t COOKIE_TABLE_AGING_INTERVAL = 3600;
77
+ static const time_t ECHO_REQUEST_INTERVAL = 60;
78
+ static const time_t ECHO_REPLY_TIMEOUT = 2;
61
79
 
62
80
  static bool age_cookie_table_enabled = false;
63
81
 
82
+ typedef struct {
83
+ uint64_t datapath_id;
84
+ uint32_t sec;
85
+ uint32_t nsec;
86
+ } echo_body;
64
87
 
65
88
  void
66
89
  usage() {
@@ -71,7 +94,9 @@ usage() {
71
94
  " -s, --socket=fd secure channnel socket\n"
72
95
  " -n, --name=SERVICE_NAME service name\n"
73
96
  " -l, --logging_level=LEVEL set logging level\n"
74
- " --no-flow-cleanup do not cleanup flows on start\n"
97
+ " --no-flow-cleanup do not cleanup flows on startup\n"
98
+ " --no-cookie-translation do not translate cookie values\n"
99
+ " --no-packet_in do not allow packet-ins on startup\n"
75
100
  " -h, --help display this help and exit\n"
76
101
  "\n"
77
102
  "DESTINATION-RULE:\n"
@@ -109,6 +134,8 @@ option_parser( int argc, char *argv[] ) {
109
134
 
110
135
  switch_info.secure_channel_fd = 0; // stdin
111
136
  switch_info.flow_cleanup = true;
137
+ switch_info.cookie_translation = true;
138
+ switch_info.deny_packet_in_on_startup = false;
112
139
  while ( ( c = getopt_long( argc, argv, short_options, long_options, NULL ) ) != -1 ) {
113
140
  switch ( c ) {
114
141
  case 's':
@@ -119,6 +146,14 @@ option_parser( int argc, char *argv[] ) {
119
146
  switch_info.flow_cleanup = false;
120
147
  break;
121
148
 
149
+ case NO_COOKIE_TRANSLATION_LONG_OPTION_VALUE:
150
+ switch_info.cookie_translation = false;
151
+ break;
152
+
153
+ case NO_PACKET_IN_LONG_OPTION_VALUE:
154
+ switch_info.deny_packet_in_on_startup = true;
155
+ break;
156
+
122
157
  default:
123
158
  usage();
124
159
  exit( EXIT_SUCCESS );
@@ -259,6 +294,13 @@ switch_event_recv_hello( struct switch_info *sw_info ) {
259
294
  // cancel to hello_wait-timeout timer
260
295
  switch_unset_timeout( switch_event_timeout_hello, NULL );
261
296
 
297
+ if ( sw_info->deny_packet_in_on_startup ) {
298
+ ret = ofpmsg_send_deny_all( sw_info );
299
+ if ( ret < 0 ) {
300
+ return ret;
301
+ }
302
+ }
303
+
262
304
  ret = ofpmsg_send_featuresrequest( sw_info );
263
305
  if ( ret < 0 ) {
264
306
  return ret;
@@ -273,6 +315,66 @@ switch_event_recv_hello( struct switch_info *sw_info ) {
273
315
  }
274
316
 
275
317
 
318
+ static void
319
+ echo_reply_timeout( void *user_data ) {
320
+ UNUSED( user_data );
321
+
322
+ error( "Echo request timeout ( datapath id %#" PRIx64 ").", switch_info.datapath_id );
323
+ switch_event_disconnected( &switch_info );
324
+ }
325
+
326
+
327
+ int
328
+ switch_event_recv_echoreply( struct switch_info *sw_info, buffer *buf ) {
329
+ if ( buf->length != sizeof( struct ofp_header ) + sizeof( echo_body ) ) {
330
+ return 0;
331
+ }
332
+ struct ofp_header *header = buf->data;
333
+ if ( ntohl( header->xid ) != sw_info->echo_request_xid ) {
334
+ return 0;
335
+ }
336
+
337
+ echo_body *body = ( echo_body * ) ( header + 1 );
338
+ if ( ntohll( body->datapath_id ) != sw_info->datapath_id ) {
339
+ return 0;
340
+ }
341
+ switch_unset_timeout( echo_reply_timeout, NULL );
342
+ struct timespec now, tim;
343
+ clock_gettime( CLOCK_MONOTONIC, &now );
344
+ tim.tv_sec = ( time_t ) ntohl( body->sec );
345
+ tim.tv_nsec = ( long ) ntohl( body->nsec );
346
+
347
+ SUB_TIMESPEC( &now, &tim, &tim );
348
+
349
+ info( "echo round-trip time %u.%09u.", ( uint32_t ) tim.tv_sec, ( uint32_t ) tim.tv_nsec );
350
+
351
+ return 0;
352
+ }
353
+
354
+
355
+ static void
356
+ echo_request_interval( void *user_data ) {
357
+ struct switch_info *sw_info = user_data;
358
+
359
+ buffer *buf = alloc_buffer();
360
+ echo_body *body = append_back_buffer( buf, sizeof( echo_body ) );
361
+ body->datapath_id = htonll( switch_info.datapath_id );
362
+ struct timespec now;
363
+ clock_gettime( CLOCK_MONOTONIC, &now );
364
+ body->sec = htonl( ( uint32_t ) now.tv_sec );
365
+ body->nsec = htonl( ( uint32_t ) now.tv_nsec );
366
+ sw_info->echo_request_xid = generate_xid();
367
+
368
+ int err = ofpmsg_send_echorequest( sw_info, sw_info->echo_request_xid, buf );
369
+ if ( err < 0 ) {
370
+ switch_event_disconnected( &switch_info );
371
+ return;
372
+ }
373
+
374
+ switch_set_timeout( ECHO_REPLY_TIMEOUT, echo_reply_timeout, NULL );
375
+ }
376
+
377
+
276
378
  int
277
379
  switch_event_recv_featuresreply( struct switch_info *sw_info, uint64_t *dpid ) {
278
380
  int ret;
@@ -323,6 +425,7 @@ switch_event_recv_featuresreply( struct switch_info *sw_info, uint64_t *dpid ) {
323
425
  return ret;
324
426
  }
325
427
  }
428
+ add_periodic_event_callback( ECHO_REQUEST_INTERVAL, echo_request_interval, sw_info );
326
429
  break;
327
430
 
328
431
  case SWITCH_STATE_COMPLETED:
@@ -342,8 +445,14 @@ switch_event_recv_featuresreply( struct switch_info *sw_info, uint64_t *dpid ) {
342
445
 
343
446
  int
344
447
  switch_event_disconnected( struct switch_info *sw_info ) {
448
+ int old_state = sw_info->state;
449
+
345
450
  sw_info->state = SWITCH_STATE_DISCONNECTED;
346
451
 
452
+ if ( old_state == SWITCH_STATE_COMPLETED ) {
453
+ delete_timer_event( echo_request_interval, sw_info );
454
+ }
455
+
347
456
  if ( sw_info->fragment_buf != NULL ) {
348
457
  free_buffer( sw_info->fragment_buf );
349
458
  sw_info->fragment_buf = NULL;
@@ -368,13 +477,16 @@ switch_event_disconnected( struct switch_info *sw_info ) {
368
477
  sw_info->secure_channel_fd = -1;
369
478
  }
370
479
 
371
- // send secure channle disconnect state to application
372
- service_send_state( sw_info, &sw_info->datapath_id, MESSENGER_OPENFLOW_DISCONNECTED );
480
+ if ( old_state != SWITCH_STATE_COMPLETED ) {
481
+ service_send_state( sw_info, &sw_info->datapath_id, MESSENGER_OPENFLOW_FAILD_TO_CONNECT );
482
+ }
483
+ else {
484
+ // send secure channle disconnect state to application
485
+ service_send_state( sw_info, &sw_info->datapath_id, MESSENGER_OPENFLOW_DISCONNECTED );
486
+ }
373
487
  flush_messenger();
374
- debug( "send disconnected state" );
375
488
 
376
- stop_event_handler();
377
- stop_messenger();
489
+ stop_trema();
378
490
 
379
491
  return 0;
380
492
  }
@@ -426,10 +538,16 @@ management_recv( uint16_t tag, void *data, size_t data_len ) {
426
538
  break;
427
539
 
428
540
  case DUMP_COOKIE_TABLE:
541
+ if ( !switch_info.cookie_translation ) {
542
+ break;
543
+ }
429
544
  dump_cookie_table();
430
545
  break;
431
546
 
432
547
  case TOGGLE_COOKIE_AGING:
548
+ if ( !switch_info.cookie_translation ) {
549
+ break;
550
+ }
433
551
  if ( age_cookie_table_enabled ) {
434
552
  delete_timer_event( age_cookie_table, NULL );
435
553
  age_cookie_table_enabled = false;
@@ -446,6 +564,22 @@ management_recv( uint16_t tag, void *data, size_t data_len ) {
446
564
  }
447
565
 
448
566
 
567
+ static void
568
+ stop_switch_daemon( void ) {
569
+ switch_event_disconnected( &switch_info );
570
+ }
571
+
572
+
573
+ static void
574
+ handle_sigterm( int signum ) {
575
+ UNUSED( signum );
576
+
577
+ if ( !set_external_callback( stop_switch_daemon ) ) {
578
+ stop_trema();
579
+ }
580
+ }
581
+
582
+
449
583
  int
450
584
  main( int argc, char *argv[] ) {
451
585
  int ret;
@@ -485,6 +619,12 @@ main( int argc, char *argv[] ) {
485
619
  }
486
620
  }
487
621
 
622
+ struct sigaction signal_exit;
623
+ memset( &signal_exit, 0, sizeof( struct sigaction ) );
624
+ signal_exit.sa_handler = handle_sigterm;
625
+ sigaction( SIGINT, &signal_exit, NULL );
626
+ sigaction( SIGTERM, &signal_exit, NULL );
627
+
488
628
  fcntl( switch_info.secure_channel_fd, F_SETFL, O_NONBLOCK );
489
629
 
490
630
  set_fd_handler( switch_info.secure_channel_fd, secure_channel_read, NULL, secure_channel_write, NULL );
@@ -499,9 +639,12 @@ main( int argc, char *argv[] ) {
499
639
  switch_info.send_queue = create_message_queue();
500
640
  switch_info.recv_queue = create_message_queue();
501
641
  switch_info.running_timer = false;
642
+ switch_info.echo_request_xid = 0;
502
643
 
503
644
  init_xid_table();
504
- init_cookie_table();
645
+ if ( switch_info.cookie_translation ) {
646
+ init_cookie_table();
647
+ }
505
648
 
506
649
  add_message_received_callback( get_trema_name(), service_recv );
507
650
 
@@ -520,7 +663,9 @@ main( int argc, char *argv[] ) {
520
663
  start_trema();
521
664
 
522
665
  finalize_xid_table();
523
- finalize_cookie_table();
666
+ if ( switch_info.cookie_translation ) {
667
+ finalize_cookie_table();
668
+ }
524
669
 
525
670
  if ( switch_info.secure_channel_fd >= 0 ) {
526
671
  delete_fd_handler( switch_info.secure_channel_fd );