trema 0.2.5 → 0.2.6

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 (292) hide show
  1. data/.gitignore +1 -1
  2. data/Doxyfile +1 -1
  3. data/Gemfile +18 -6
  4. data/README.md +112 -5
  5. data/Rakefile +3 -1
  6. data/Rantfile +88 -1
  7. data/bin/trema +248 -0
  8. data/bin/trema-config +59 -0
  9. data/cruise.rb +1 -1
  10. data/features/example.dumper.feature +45 -65
  11. data/features/example.hello_trema.feature +21 -0
  12. data/features/example.learning_switch.feature +26 -28
  13. data/features/example.list_switches.feature +19 -33
  14. data/features/example.message.echo_reply.feature +10 -10
  15. data/features/example.message.echo_request.feature +2 -2
  16. data/features/example.message.features_request.feature +6 -5
  17. data/features/example.message.hello.feature +47 -13
  18. data/features/example.message.set_config.feature +4 -4
  19. data/features/example.message.vendor-action.feature +23 -0
  20. data/features/example.multi_learning_switch.feature +14 -42
  21. data/features/example.packet_in.feature +31 -0
  22. data/features/example.packetin_filter_config.feature +11 -7
  23. data/features/example.patch_panel.feature +29 -0
  24. data/features/example.repeater_hub.feature +43 -40
  25. data/features/example.switch_info.feature +51 -0
  26. data/features/example.switch_monitor.feature +24 -42
  27. data/features/packetin_filter.feature +28 -22
  28. data/features/step_definitions/misc_steps.rb +19 -8
  29. data/features/step_definitions/send_packets_steps.rb +1 -10
  30. data/features/step_definitions/stats_steps.rb +4 -4
  31. data/features/support/env.rb +2 -1
  32. data/features/support/hooks.rb +35 -2
  33. data/features/switch_manager.feature +18 -12
  34. data/features/trema-config.feature +26 -39
  35. data/features/trema.dump_flows.feature +26 -12
  36. data/features/trema.help.feature +26 -0
  37. data/features/trema.kill.feature +39 -41
  38. data/features/trema.killall.feature +23 -23
  39. data/features/trema.reset_stats.feature +50 -10
  40. data/features/trema.run.feature +28 -39
  41. data/features/trema.send_packets.feature +29 -40
  42. data/features/trema.show_stats.feature +30 -33
  43. data/features/trema.up.feature +33 -0
  44. data/features/trema.version.feature +9 -0
  45. data/ruby/extconf.rb +7 -0
  46. data/ruby/trema/aggregate-stats-reply.rb +3 -3
  47. data/ruby/trema/app.rb +5 -1
  48. data/ruby/trema/barrier-request.c +55 -30
  49. data/ruby/trema/cli.rb +8 -8
  50. data/ruby/trema/command.rb +1 -3
  51. data/ruby/trema/command/dump_flows.rb +5 -24
  52. data/ruby/trema/command/kill.rb +31 -36
  53. data/ruby/trema/command/killall.rb +1 -19
  54. data/{features/step_definitions/kill_steps.rb → ruby/trema/command/netns.rb} +13 -5
  55. data/ruby/trema/command/reset_stats.rb +3 -23
  56. data/ruby/trema/command/ruby.rb +2 -19
  57. data/ruby/trema/command/run.rb +6 -27
  58. data/ruby/trema/command/send_packets.rb +6 -90
  59. data/ruby/trema/command/show_stats.rb +21 -40
  60. data/ruby/trema/command/up.rb +5 -26
  61. data/ruby/trema/command/version.rb +1 -5
  62. data/ruby/trema/controller.c +14 -16
  63. data/ruby/trema/custom-switch.rb +56 -0
  64. data/ruby/trema/desc-stats-reply.rb +5 -5
  65. data/ruby/trema/dsl/configuration.rb +4 -0
  66. data/{features/step_definitions/up_steps.rb → ruby/trema/dsl/custom-switch.rb} +18 -4
  67. data/ruby/trema/dsl/netns.rb +78 -0
  68. data/ruby/trema/dsl/parser.rb +2 -0
  69. data/ruby/trema/dsl/runner.rb +8 -0
  70. data/ruby/trema/dsl/syntax.rb +18 -0
  71. data/ruby/trema/echo-reply.h +2 -2
  72. data/ruby/trema/echo-request.c +3 -5
  73. data/ruby/trema/enqueue.rb +2 -2
  74. data/ruby/trema/error.c +3 -3
  75. data/ruby/trema/executables.rb +26 -2
  76. data/ruby/trema/features-request.c +3 -5
  77. data/ruby/trema/flow-removed.c +6 -6
  78. data/ruby/trema/flow-stats-reply.rb +6 -8
  79. data/ruby/trema/flow.rb +12 -1
  80. data/ruby/trema/get-config-request.c +55 -28
  81. data/ruby/trema/hello.c +3 -5
  82. data/ruby/trema/host.rb +8 -0
  83. data/ruby/trema/list-switches-reply.c +1 -1
  84. data/ruby/trema/mac.rb +1 -1
  85. data/ruby/trema/match.c +15 -14
  86. data/ruby/trema/monkey-patch/module/deprecation.rb +0 -2
  87. data/ruby/trema/netns.rb +127 -0
  88. data/ruby/trema/ordered-hash.rb +5 -4
  89. data/ruby/trema/packet-in.c +136 -113
  90. data/ruby/trema/packet-queue.rb +9 -9
  91. data/ruby/trema/packetin-filter.rb +1 -1
  92. data/ruby/trema/phost.rb +16 -7
  93. data/ruby/trema/port-mod.c +6 -5
  94. data/ruby/trema/port-stats-reply.rb +2 -2
  95. data/ruby/trema/process.rb +29 -0
  96. data/ruby/trema/queue-stats-reply.rb +2 -4
  97. data/ruby/trema/send-out-port.rb +5 -3
  98. data/ruby/trema/set-eth-addr.rb +4 -0
  99. data/ruby/trema/set-ip-addr.rb +4 -2
  100. data/ruby/trema/set-ip-dst-addr.rb +2 -1
  101. data/ruby/trema/set-ip-src-addr.rb +2 -1
  102. data/ruby/trema/set-ip-tos.rb +3 -2
  103. data/ruby/trema/set-transport-port.rb +3 -2
  104. data/ruby/trema/set-vlan-priority.rb +3 -2
  105. data/ruby/trema/set-vlan-vid.rb +5 -4
  106. data/ruby/trema/shell/reset_stats.rb +2 -1
  107. data/ruby/trema/shell/run.rb +1 -1
  108. data/ruby/trema/shell/send_packets.rb +1 -1
  109. data/ruby/trema/shell/show_stats.rb +1 -1
  110. data/ruby/trema/stats-helper.rb +3 -3
  111. data/ruby/trema/stats-reply.c +26 -17
  112. data/ruby/trema/stats-request.c +39 -41
  113. data/ruby/trema/switch-daemon.rb +36 -31
  114. data/ruby/trema/switch.c +1 -1
  115. data/ruby/trema/table-stats-reply.rb +1 -1
  116. data/ruby/trema/timers.rb +13 -13
  117. data/ruby/trema/trema.c +3 -3
  118. data/ruby/trema/tremashark.rb +9 -2
  119. data/ruby/trema/util.rb +39 -15
  120. data/ruby/trema/vendor-action.rb +8 -3
  121. data/ruby/trema/vendor-stats-reply.rb +4 -6
  122. data/ruby/trema/vendor.c +1 -1
  123. data/ruby/trema/version.rb +1 -1
  124. data/spec/trema/barrier-request_spec.rb +47 -37
  125. data/spec/trema/controller_spec.rb +1 -0
  126. data/spec/trema/dsl/runner_spec.rb +8 -3
  127. data/spec/trema/dsl/vhost_spec.rb +8 -8
  128. data/spec/trema/echo-request_spec.rb +1 -0
  129. data/spec/trema/features-request_spec.rb +1 -0
  130. data/spec/trema/flow-removed_spec.rb +9 -9
  131. data/spec/trema/get-config-request_spec.rb +51 -39
  132. data/spec/trema/match_spec.rb +1 -1
  133. data/spec/trema/openflow-error_spec.rb +11 -11
  134. data/spec/trema/packet-out_spec.rb +5 -5
  135. data/spec/trema/queue-get-config-reply_spec.rb +1 -1
  136. data/spec/trema/queue-get-config-request_spec.rb +1 -1
  137. data/spec/trema/set-eth-dst-addr_spec.rb +1 -1
  138. data/spec/trema/set-eth-src-addr_spec.rb +1 -1
  139. data/spec/trema/set-ip-dst-addr_spec.rb +1 -0
  140. data/spec/trema/set-ip-src-addr_spec.rb +1 -0
  141. data/spec/trema/set-ip-tos_spec.rb +1 -0
  142. data/spec/trema/set-transport-dst-port_spec.rb +1 -0
  143. data/spec/trema/set-transport-src-port_spec.rb +1 -0
  144. data/spec/trema/set-vlan-priority_spec.rb +1 -0
  145. data/spec/trema/set-vlan-vid_spec.rb +2 -1
  146. data/spec/trema/stats-reply_spec.rb +38 -36
  147. data/spec/trema/stats-request_spec.rb +6 -6
  148. data/spec/trema/strip-vlan-header_spec.rb +1 -0
  149. data/spec/trema/util_spec.rb +3 -2
  150. data/spec/trema/vendor-action_spec.rb +9 -8
  151. data/src/examples/dumper/dumper.c +8 -6
  152. data/src/examples/dumper/dumper.rb +1 -1
  153. data/{features/step_definitions/killall_steps.rb → src/examples/hello_trema/hello-trema.rb} +6 -5
  154. data/src/examples/hello_trema/hello_trema.c +4 -4
  155. data/src/examples/learning_switch/learning_switch.c +1 -1
  156. data/src/examples/list_switches/list_switches.c +2 -2
  157. data/src/examples/match_compare/match-compare.rb +2 -2
  158. data/src/examples/multi_learning_switch/multi-learning-switch.rb +1 -1
  159. data/src/examples/multi_learning_switch/multi_learning_switch.c +3 -3
  160. data/src/examples/openflow_message/README +1 -1
  161. data/src/examples/openflow_message/echo-request.rb +1 -1
  162. data/src/examples/openflow_message/features_request.c +21 -21
  163. data/src/examples/openflow_message/hello.c +1 -3
  164. data/src/examples/openflow_message/hello.rb +9 -24
  165. data/src/examples/{hello_trema/hello_trema.rb → openflow_message/vendor-action.rb} +17 -7
  166. data/src/examples/openflow_message/vendor_action.c +105 -0
  167. data/src/examples/openflow_switch/hello_switch.c +81 -0
  168. data/src/examples/packet_in/packet-in.rb +9 -13
  169. data/src/examples/packetin_filter_config/packetin_filter_config.c +2 -2
  170. data/src/examples/patch_panel/network.conf +14 -0
  171. data/src/examples/patch_panel/patch-panel.conf +1 -0
  172. data/{features/step_definitions/show_stats_steps.rb → src/examples/patch_panel/patch-panel.rb} +29 -13
  173. data/src/examples/switch_info/{switch_info.rb → switch-info.rb} +2 -2
  174. data/src/examples/switch_info/switch_info.c +4 -4
  175. data/src/examples/switch_monitor/switch_monitor.c +3 -3
  176. data/src/examples/traffic_monitor/counter.c +9 -9
  177. data/src/examples/traffic_monitor/fdb.c +9 -9
  178. data/src/lib/arp.h +1 -1
  179. data/src/lib/buffer.c +4 -3
  180. data/src/lib/byteorder.c +31 -5
  181. data/src/lib/byteorder.h +2 -2
  182. data/src/lib/chibach.c +8 -6
  183. data/src/lib/daemon.c +29 -3
  184. data/src/lib/doubly_linked_list.c +6 -1
  185. data/src/lib/ether.c +1 -1
  186. data/src/lib/ether.h +1 -1
  187. data/src/lib/event_handler.c +3 -3
  188. data/src/lib/hash_table.c +1 -1
  189. data/src/lib/linked_list.c +50 -2
  190. data/src/lib/linked_list.h +2 -2
  191. data/src/lib/log.c +122 -22
  192. data/src/lib/log.h +13 -9
  193. data/src/lib/management_interface.c +361 -0
  194. data/src/lib/management_interface.h +42 -0
  195. data/src/lib/management_service_interface.c +104 -0
  196. data/src/lib/management_service_interface.h +136 -0
  197. data/src/lib/match_table.c +5 -5
  198. data/src/lib/message_queue.c +5 -3
  199. data/src/lib/message_queue.h +1 -1
  200. data/src/lib/messenger.c +73 -39
  201. data/src/lib/messenger.h +3 -2
  202. data/src/lib/openflow_application_interface.c +17 -17
  203. data/src/lib/openflow_message.c +175 -23
  204. data/src/lib/openflow_message.h +2 -1
  205. data/src/lib/openflow_switch_interface.c +12 -12
  206. data/src/lib/packet_parser.c +11 -32
  207. data/src/lib/packetin_filter_interface.c +5 -5
  208. data/src/lib/persistent_storage.c +7 -7
  209. data/src/lib/secure_channel.c +6 -6
  210. data/src/lib/secure_channel.h +1 -1
  211. data/src/lib/stat.c +54 -17
  212. data/src/lib/stat.h +9 -0
  213. data/src/lib/timer.c +11 -10
  214. data/src/lib/trema.c +38 -9
  215. data/src/lib/trema.h +1 -0
  216. data/src/lib/trema_private.h +6 -0
  217. data/src/lib/trema_wrapper.c +4 -4
  218. data/src/lib/trema_wrapper.h +10 -10
  219. data/src/lib/utility.c +6 -6
  220. data/src/management/application.c +224 -0
  221. data/src/management/echo.c +185 -0
  222. data/src/management/set_logging_level.c +153 -0
  223. data/src/management/show_stats.c +150 -0
  224. data/src/management/trema_manager +184 -0
  225. data/src/packetin_filter/packetin_filter.c +31 -29
  226. data/src/switch_manager/cookie_table.c +7 -7
  227. data/src/switch_manager/dpid_table.c +3 -3
  228. data/src/switch_manager/dpid_table.h +0 -1
  229. data/src/switch_manager/management_interface.h +0 -1
  230. data/src/switch_manager/ofpmsg_recv.c +3 -3
  231. data/src/switch_manager/ofpmsg_recv.h +0 -1
  232. data/src/switch_manager/ofpmsg_send.c +2 -2
  233. data/src/switch_manager/ofpmsg_send.h +0 -1
  234. data/src/switch_manager/secure_channel_listener.c +2 -2
  235. data/src/switch_manager/secure_channel_receiver.c +2 -2
  236. data/src/switch_manager/secure_channel_receiver.h +0 -1
  237. data/src/switch_manager/secure_channel_sender.c +8 -1
  238. data/src/switch_manager/service_interface.c +5 -4
  239. data/src/switch_manager/switch.c +79 -53
  240. data/src/switch_manager/switch_manager.c +24 -22
  241. data/src/switch_manager/xid_table.c +6 -6
  242. data/src/switch_manager/xid_table.h +0 -1
  243. data/src/tremashark/README +4 -3
  244. data/src/tremashark/packet_capture.c +11 -9
  245. data/src/tremashark/pcap_queue.c +2 -2
  246. data/src/tremashark/pcap_queue.h +2 -2
  247. data/src/tremashark/plugin/packet-trema/Makefile +1 -1
  248. data/src/tremashark/plugin/packet-trema/Makefile.common +1 -1
  249. data/src/tremashark/plugin/packet-trema/packet-trema.c +50 -37
  250. data/src/tremashark/queue.c +5 -4
  251. data/src/tremashark/queue.h +1 -1
  252. data/src/tremashark/stdin_relay.c +10 -8
  253. data/src/tremashark/syslog_relay.c +14 -12
  254. data/src/tremashark/tremashark.c +15 -18
  255. data/trema +2 -96
  256. data/trema-config +2 -52
  257. data/trema.gemspec +12 -1
  258. data/unittests/cmockery_trema.h +14 -13
  259. data/unittests/lib/buffer_test.c +1 -1
  260. data/unittests/lib/byteorder_test.c +108 -25
  261. data/unittests/lib/daemon_test.c +141 -5
  262. data/unittests/lib/doubly_linked_list_test.c +5 -1
  263. data/unittests/lib/ether_test.c +4 -4
  264. data/unittests/lib/hash_table_test.c +5 -3
  265. data/unittests/lib/linked_list_test.c +82 -4
  266. data/unittests/lib/log_test.c +96 -5
  267. data/unittests/lib/management_interface_test.c +240 -0
  268. data/unittests/lib/management_service_interface_test.c +319 -0
  269. data/unittests/lib/message_queue_test.c +6 -2
  270. data/unittests/lib/messenger_test.c +167 -2
  271. data/unittests/lib/openflow_application_interface_test.c +16 -22
  272. data/unittests/lib/openflow_message_test.c +721 -24
  273. data/unittests/lib/packet_info_test.c +2 -2
  274. data/unittests/lib/packet_parser_test.c +15 -16
  275. data/unittests/lib/packetin_filter_interface_test.c +6 -6
  276. data/unittests/lib/persistent_storage_test.c +11 -11
  277. data/unittests/lib/stat_test.c +151 -7
  278. data/unittests/lib/timer_test.c +1 -1
  279. data/unittests/lib/trema_private_test.c +2 -2
  280. data/unittests/lib/trema_test.c +40 -12
  281. data/unittests/lib/utility_test.c +3 -3
  282. data/unittests/lib/wrapper_test.c +3 -3
  283. data/unittests/packetin_filter/packetin_filter_test.c +12 -11
  284. data/unittests/switch_manager/switch_manager_test.c +29 -22
  285. metadata +99 -20
  286. data/features/step_definitions/log_steps.rb +0 -90
  287. data/features/step_definitions/run_steps.rb +0 -91
  288. data/features/trema.feature +0 -27
  289. data/features/tutorial.hello_trema.feature +0 -27
  290. data/features/tutorial.packet_in.feature +0 -47
  291. data/features/tutorial.switch_info.feature +0 -55
  292. data/ruby/trema/command/usage.rb +0 -63
@@ -0,0 +1,361 @@
1
+ /*
2
+ * Author: Yasunobu Chiba
3
+ *
4
+ * Copyright (C) 2012 NEC Corporation
5
+ *
6
+ * This program is free software; you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License, version 2, as
8
+ * published by the Free Software Foundation.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License along
16
+ * with this program; if not, write to the Free Software Foundation, Inc.,
17
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
+ */
19
+
20
+
21
+ #include <assert.h>
22
+ #include <string.h>
23
+ #include "bool.h"
24
+ #include "checks.h"
25
+ #include "log.h"
26
+ #include "management_interface.h"
27
+ #include "management_service_interface.h"
28
+ #include "trema.h" // FIXME: don't include trema.h here (move get_trema_name() to trema_private.c)
29
+ #include "trema_private.h"
30
+ #include "trema_wrapper.h"
31
+ #include "wrapper.h"
32
+
33
+
34
+ static bool initialized = false;
35
+ static management_application_request_handler application_callback = NULL;
36
+ static void *application_user_data = NULL;
37
+
38
+
39
+ static void
40
+ handle_echo_request( const messenger_context_handle *handle, management_echo_request *request ) {
41
+ assert( handle != NULL );
42
+ assert( request != NULL );
43
+ assert( ntohs( request->header.type ) == MANAGEMENT_ECHO_REQUEST );
44
+ assert( ntohl( request->header.length ) == sizeof( management_echo_request ) );
45
+
46
+ debug( "Handling an echo request from %s ( sent_at = %u.%09u ).",
47
+ handle->service_name, ntohl( request->sent_at.tv_sec ), ntohl( request->sent_at.tv_nsec ) );
48
+
49
+ bool ret = true;
50
+ management_echo_reply reply;
51
+ memset( &reply, 0, sizeof( management_echo_reply ) );
52
+ reply.header.type = htons( MANAGEMENT_ECHO_REPLY );
53
+ reply.header.length = htonl( sizeof( management_echo_reply ) );
54
+ reply.sent_at = request->sent_at;
55
+
56
+ struct timespec now = { 0, 0 };
57
+ int retval = clock_gettime( CLOCK_REALTIME, &now );
58
+ if ( retval < 0 ) {
59
+ error( "Failed to retrieve clock." );
60
+ ret = false;
61
+ }
62
+ reply.received_at.tv_sec = htonl( ( uint32_t ) now.tv_sec );
63
+ reply.received_at.tv_nsec = htonl( ( uint32_t ) now.tv_nsec );
64
+ reply.header.status = ( uint8_t ) ( ret == true ? MANAGEMENT_REQUEST_SUCCEEDED : MANAGEMENT_REQUEST_FAILED );
65
+
66
+ ret = send_reply_message( handle, MESSENGER_MANAGEMENT_REPLY, &reply, sizeof( management_echo_reply ) );
67
+ if ( ret == false ) {
68
+ error( "Failed to send an echo reply." );
69
+ }
70
+ }
71
+
72
+
73
+ static void
74
+ handle_set_logging_level_request( const messenger_context_handle *handle, management_set_logging_level_request *request ) {
75
+ assert( handle != NULL );
76
+ assert( request != NULL );
77
+ assert( ntohs( request->header.type ) == MANAGEMENT_SET_LOGGING_LEVEL_REQUEST );
78
+ assert( ntohl( request->header.length ) == sizeof( management_set_logging_level_request ) );
79
+
80
+ request->level[ LOGGING_LEVEL_STR_LENGTH - 1 ] = '\0';
81
+
82
+ debug( "Handling a set logging level request from %s ( level = %s ).", handle->service_name, request->level );
83
+
84
+ management_set_logging_level_reply reply;
85
+ memset( &reply, 0, sizeof( management_set_logging_level_reply ) );
86
+ reply.header.type = htons( MANAGEMENT_SET_LOGGING_LEVEL_REPLY );
87
+ reply.header.length = htonl( sizeof( management_set_logging_level_reply ) );
88
+
89
+ bool ret = valid_logging_level( request->level );
90
+ if ( ret ) {
91
+ ret = set_logging_level( request->level );
92
+ }
93
+
94
+ if ( ret ) {
95
+ reply.header.status = MANAGEMENT_REQUEST_SUCCEEDED;
96
+ }
97
+ else {
98
+ reply.header.status = MANAGEMENT_REQUEST_FAILED;
99
+ }
100
+
101
+ ret = send_reply_message( handle, MESSENGER_MANAGEMENT_REPLY, &reply, sizeof( management_set_logging_level_reply ) );
102
+ if ( ret == false ) {
103
+ error( "Failed to send a set logging level reply." );
104
+ }
105
+ }
106
+
107
+
108
+ static void
109
+ append_stat( const char *key, const uint64_t value, void *user_data ) {
110
+ assert( key != NULL );
111
+ assert( user_data != NULL );
112
+
113
+ list_element **stats = user_data;
114
+
115
+ stat_entry *entry = xmalloc( sizeof( stat_entry ) );
116
+ memset( entry, 0, sizeof( stat_entry ) );
117
+ memcpy( entry->key, key, sizeof( entry->key ) );
118
+ entry->value = htonll( value );
119
+
120
+ append_to_tail( stats, entry );
121
+ }
122
+
123
+
124
+ static void
125
+ handle_show_stats_request( const messenger_context_handle *handle, management_show_stats_request *request ) {
126
+ assert( handle != NULL );
127
+ assert( request != NULL );
128
+ assert( ntohs( request->header.type ) == MANAGEMENT_SHOW_STATS_REQUEST );
129
+ assert( ntohl( request->header.length ) == sizeof( management_show_stats_request ) );
130
+
131
+ debug( "Handling a show stats request from %s.", handle->service_name );
132
+
133
+ list_element *stats = NULL;
134
+ create_list( &stats );
135
+ foreach_stat( append_stat, &stats );
136
+ unsigned int n_stats = list_length_of( stats );
137
+
138
+ const size_t send_queue_length = 400000; // MESSENGER_RECV_BUFFER * 4
139
+ const size_t send_queue_margin = 256; // headroom for various headers
140
+ unsigned int n_max_entries = ( unsigned int ) ( send_queue_length - send_queue_margin ) / sizeof( stat_entry );
141
+
142
+ management_show_stats_reply *reply = NULL;
143
+ size_t length = 0;
144
+
145
+ if ( n_stats <= n_max_entries ) {
146
+ length = offsetof( management_show_stats_reply, entries ) + sizeof( stat_entry ) * n_stats;
147
+ reply = xmalloc( length );
148
+ memset( reply, 0, length );
149
+ reply->header.type = htons( MANAGEMENT_SHOW_STATS_REPLY );
150
+ reply->header.length = htonl( ( uint32_t ) length );
151
+ reply->header.status = MANAGEMENT_REQUEST_SUCCEEDED;
152
+
153
+ stat_entry *p = reply->entries;
154
+ for ( list_element *e = stats; e != NULL; e = e->next ) {
155
+ assert( e->data != NULL );
156
+ memcpy( p, e->data, sizeof( stat_entry ) );
157
+ p++;
158
+ }
159
+ }
160
+ else {
161
+ // TODO: Send statistics via out-of-band channel or by multiple replies.
162
+
163
+ error( "Too many statistic entries ( %u > %u ).", n_stats, n_max_entries );
164
+
165
+ length = offsetof( management_show_stats_reply, entries );
166
+ reply = xmalloc( length );
167
+ memset( reply, 0, length );
168
+ reply->header.type = htons( MANAGEMENT_SHOW_STATS_REPLY );
169
+ reply->header.length = htonl( ( uint32_t ) length );
170
+ reply->header.status = MANAGEMENT_REQUEST_FAILED;
171
+ }
172
+
173
+ if ( stats != NULL ) {
174
+ for ( list_element *e = stats; e != NULL; e = e->next ) {
175
+ assert( e->data != NULL );
176
+ xfree( e->data );
177
+ }
178
+ delete_list( stats );
179
+ }
180
+
181
+ bool ret = send_reply_message( handle, MESSENGER_MANAGEMENT_REPLY, reply, length );
182
+ if ( ret == false ) {
183
+ error( "Failed to send a show stats reply." );
184
+ }
185
+ xfree( reply );
186
+ }
187
+
188
+
189
+ void
190
+ _set_management_application_request_handler( management_application_request_handler callback, void *user_data ) {
191
+ application_callback = callback;
192
+ application_user_data = user_data;
193
+ }
194
+
195
+
196
+ static void
197
+ handle_application_request( const messenger_context_handle *handle, management_application_request *request ) {
198
+ assert( handle != NULL );
199
+ assert( request != NULL );
200
+ assert( ntohs( request->header.type ) == MANAGEMENT_APPLICATION_REQUEST );
201
+ assert( ntohl( request->header.length ) >= offsetof( management_application_request, data ) );
202
+
203
+ debug( "Handling an application specific management request from %s ( application_id = %#x ).",
204
+ handle->service_name, request->application_id );
205
+
206
+ if ( application_callback != NULL ) {
207
+ size_t length = ( size_t ) ntohl( request->header.length ) - offsetof( management_application_request, data );
208
+ void *data = NULL;
209
+ if ( length > 0 ) {
210
+ data = request->data;
211
+ }
212
+ application_callback( handle, ntohl( request->application_id ), data, length, application_user_data );
213
+ }
214
+ else {
215
+ management_application_reply *reply = create_management_application_reply( MANAGEMENT_REQUEST_FAILED,
216
+ ntohl( request->application_id ), NULL, 0 );
217
+ send_management_application_reply( handle, reply );
218
+ xfree( reply );
219
+ }
220
+ }
221
+
222
+
223
+ static void
224
+ handle_management_request( const messenger_context_handle *handle, void *data, size_t length ) {
225
+ assert( handle != NULL );
226
+ assert( data != NULL );
227
+ assert( length >= sizeof( management_request_header ) );
228
+
229
+ management_request_header *header = data;
230
+
231
+ assert( length == ( size_t ) ntohl( header->length ) );
232
+
233
+ switch ( ntohs( header->type ) ) {
234
+ case MANAGEMENT_ECHO_REQUEST:
235
+ {
236
+ if ( length != sizeof( management_echo_request ) ) {
237
+ error( "Invalid echo request ( length = %zu ).", length );
238
+ return;
239
+ }
240
+
241
+ handle_echo_request( handle, data );
242
+ }
243
+ break;
244
+
245
+ case MANAGEMENT_SET_LOGGING_LEVEL_REQUEST:
246
+ {
247
+ if ( length != sizeof( management_set_logging_level_request ) ) {
248
+ error( "Invalid set logging level request ( length = %zu ).", length );
249
+ return;
250
+ }
251
+
252
+ handle_set_logging_level_request( handle, data );
253
+ }
254
+ break;
255
+
256
+ case MANAGEMENT_SHOW_STATS_REQUEST:
257
+ {
258
+ if ( length != sizeof( management_show_stats_request ) ) {
259
+ error( "Invalid show stats request ( length = %zu ).", length );
260
+ return;
261
+ }
262
+
263
+ handle_show_stats_request( handle, data );
264
+ }
265
+ break;
266
+
267
+ case MANAGEMENT_APPLICATION_REQUEST:
268
+ {
269
+ if ( length < offsetof( management_application_request, data ) ) {
270
+ error( "Invalid application specific management request ( length = %zu ).", length );
271
+ return;
272
+ }
273
+
274
+ handle_application_request( handle, data );
275
+ }
276
+ break;
277
+
278
+ default:
279
+ {
280
+ error( "Undefined management request type ( type = %#x ).", header->type );
281
+ }
282
+ break;
283
+ }
284
+ }
285
+
286
+
287
+ static void
288
+ handle_request( const messenger_context_handle *handle, uint16_t tag, void *data, size_t length ) {
289
+ assert( handle != NULL );
290
+
291
+ debug( "Handling a request ( handle = %p, tag = %#x, data = %p, length = %zu ).",
292
+ handle, tag, data, length );
293
+
294
+ switch ( tag ) {
295
+ case MESSENGER_MANAGEMENT_REQUEST:
296
+ {
297
+ if ( length < sizeof( management_request_header ) ) {
298
+ error( "Invalid management request. Too short message ( length = %zu ).", length );
299
+ return;
300
+ }
301
+
302
+ handle_management_request( handle, data, length );
303
+ }
304
+ break;
305
+
306
+ default:
307
+ {
308
+ warn( "Undefined request tag ( tag = %#x ).", tag );
309
+ }
310
+ break;
311
+ }
312
+ }
313
+
314
+
315
+ bool
316
+ init_management_interface() {
317
+ if ( initialized ) {
318
+ error( "Management interface is already initialized." );
319
+ return false;
320
+ }
321
+
322
+ add_message_requested_callback( get_management_service_name( get_trema_name() ), handle_request );
323
+
324
+ initialized = true;
325
+
326
+ debug( "Management interface is initialized ( trema_name = %s, service_name = %s ).",
327
+ get_trema_name(), get_management_service_name( get_trema_name() ) );
328
+
329
+ return true;
330
+ }
331
+
332
+
333
+ bool
334
+ finalize_management_interface() {
335
+ if ( !initialized ) {
336
+ error( "Management interface is not initialized yet or already finalized." );
337
+ return false;
338
+ }
339
+
340
+ delete_message_requested_callback( get_management_service_name( get_trema_name() ), handle_request );
341
+
342
+ initialized = false;
343
+
344
+ debug( "Management interface is finalized ( trema_name = %s ).", get_trema_name() );
345
+
346
+ return true;
347
+ }
348
+
349
+
350
+ bool *
351
+ _get_management_interface_initialized() {
352
+ return &initialized;
353
+ }
354
+
355
+
356
+ /*
357
+ * Local variables:
358
+ * c-basic-offset: 2
359
+ * indent-tabs-mode: nil
360
+ * End:
361
+ */
@@ -0,0 +1,42 @@
1
+ /*
2
+ * A management interface library
3
+ *
4
+ * Author: Yasunobu Chiba
5
+ *
6
+ * Copyright (C) 2012 NEC Corporation
7
+ *
8
+ * This program is free software; you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License, version 2, as
10
+ * published by the Free Software Foundation.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License along
18
+ * with this program; if not, write to the Free Software Foundation, Inc.,
19
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
+ */
21
+
22
+
23
+ #ifndef MANAGEMENT_INTERFACE_H
24
+ #define MANAGEMENT_INTERFACE_H
25
+
26
+
27
+ #include "bool.h"
28
+
29
+
30
+ bool init_management_interface();
31
+ bool finalize_management_interface();
32
+
33
+
34
+ #endif // MANAGEMENT_INTERFACE_H
35
+
36
+
37
+ /*
38
+ * Local variables:
39
+ * c-basic-offset: 2
40
+ * indent-tabs-mode: nil
41
+ * End:
42
+ */
@@ -0,0 +1,104 @@
1
+ /*
2
+ * Author: Yasunobu Chiba
3
+ *
4
+ * Copyright (C) 2012 NEC Corporation
5
+ *
6
+ * This program is free software; you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License, version 2, as
8
+ * published by the Free Software Foundation.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License along
16
+ * with this program; if not, write to the Free Software Foundation, Inc.,
17
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
+ */
19
+
20
+
21
+ #include <arpa/inet.h>
22
+ #include <assert.h>
23
+ #include <string.h>
24
+ #include "bool.h"
25
+ #include "checks.h"
26
+ #include "log.h"
27
+ #include "management_service_interface.h"
28
+ #include "messenger.h"
29
+ #include "trema_private.h"
30
+ #include "trema_wrapper.h"
31
+ #include "utility.h"
32
+ #include "wrapper.h"
33
+
34
+
35
+ static char management_service_name[ MESSENGER_SERVICE_NAME_LENGTH ];
36
+
37
+
38
+ static const char *
39
+ _get_management_service_name( const char *service_name ) {
40
+ if ( service_name == NULL ) {
41
+ die( "Service name must not be NULL." );
42
+ }
43
+ if ( strlen( service_name ) == 0 ) {
44
+ die( "Service name length must not be zero." );
45
+ }
46
+ if ( strlen( service_name ) >= ( MESSENGER_SERVICE_NAME_LENGTH - 2 ) ) {
47
+ die( "Too long service name ( %s ).", service_name );
48
+ }
49
+
50
+ memset( management_service_name, '\0', MESSENGER_SERVICE_NAME_LENGTH );
51
+ snprintf( management_service_name, MESSENGER_SERVICE_NAME_LENGTH, "%s.m", service_name );
52
+
53
+ return management_service_name;
54
+ }
55
+ const char *( *get_management_service_name )( const char *service_name ) = _get_management_service_name;
56
+
57
+
58
+ management_application_reply *
59
+ _create_management_application_reply( uint8_t status, uint32_t application_id, void *data, size_t data_length ) {
60
+ size_t length = offsetof( management_application_reply, data );
61
+ if ( data != NULL ) {
62
+ length += data_length;
63
+ }
64
+ management_application_reply *reply = xmalloc( length );
65
+ memset( reply, 0, length );
66
+ reply->header.type = htons( MANAGEMENT_APPLICATION_REPLY );
67
+ reply->header.status = status;
68
+ reply->header.length = htonl( ( uint32_t ) length );
69
+ reply->application_id = htonl( application_id );
70
+ if ( data != NULL ) {
71
+ memcpy( reply->data, data, data_length );
72
+ }
73
+
74
+ return reply;
75
+ }
76
+ management_application_reply *( *create_management_application_reply )( uint8_t status, uint32_t application_id, void *data, size_t data_length ) = _create_management_application_reply;
77
+
78
+
79
+ bool
80
+ _send_management_application_reply( const messenger_context_handle *handle, const management_application_reply *reply ) {
81
+ if ( handle == NULL || reply == NULL ) {
82
+ error( "Both context handle and reply message must not be NULL ( handle = %p, reply = %p ).", handle, reply );
83
+ return false;
84
+ }
85
+ bool ret = send_reply_message( handle, MESSENGER_MANAGEMENT_REPLY, reply, ( size_t ) ntohl( reply->header.length ) );
86
+ if ( !ret ) {
87
+ error( "Failed to send an application specific management reply." );
88
+ return false;
89
+ }
90
+
91
+ return true;
92
+ }
93
+ bool ( *send_management_application_reply )( const messenger_context_handle *handle, const management_application_reply *reply ) = _send_management_application_reply;
94
+
95
+
96
+ void ( *set_management_application_request_handler )( management_application_request_handler callback, void *user_data ) = _set_management_application_request_handler;
97
+
98
+
99
+ /*
100
+ * Local variables:
101
+ * c-basic-offset: 2
102
+ * indent-tabs-mode: nil
103
+ * End:
104
+ */