trema 0.4.6 → 0.4.7

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 (291) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -0
  3. data/.travis.yml +24 -7
  4. data/Gemfile +19 -27
  5. data/Guardfile +6 -0
  6. data/README.md +13 -5
  7. data/Rakefile +418 -415
  8. data/bin/quality +2 -2
  9. data/bin/trema +103 -105
  10. data/bin/trema-config +7 -7
  11. data/build.rb +2 -2
  12. data/cruise.rb +109 -83
  13. data/features/dsl/switch_port_specifier.feature +1 -1
  14. data/features/examples/dumper.feature +9 -41
  15. data/features/examples/hello_trema.feature +1 -1
  16. data/features/examples/learning_switch.feature +7 -7
  17. data/features/examples/list_switches.feature +5 -5
  18. data/features/examples/message.set_config.feature +11 -11
  19. data/features/examples/message.vendor-action.feature +7 -7
  20. data/features/examples/message.vendor-stats-request.feature +1 -1
  21. data/features/examples/multi_learning_switch.feature +7 -7
  22. data/features/examples/openflow_message.echo.feature +15 -15
  23. data/features/examples/openflow_message.features_request.feature +12 -12
  24. data/features/examples/openflow_message.hello.feature +13 -13
  25. data/features/examples/packet_in.feature +8 -8
  26. data/features/examples/patch_panel.feature +1 -1
  27. data/features/examples/repeater_hub.feature +7 -7
  28. data/features/examples/switch_info.feature +16 -16
  29. data/features/examples/switch_monitor.feature +11 -11
  30. data/features/examples/transparent_firewall.feature +73 -0
  31. data/features/handlers/switch_ready.feature +1 -1
  32. data/features/step_definitions/misc_steps.rb +24 -24
  33. data/features/step_definitions/send_packets_steps.rb +2 -2
  34. data/features/step_definitions/stats_steps.rb +6 -6
  35. data/features/support/env.rb +15 -15
  36. data/features/support/hooks.rb +9 -9
  37. data/features/switch_event/add_forward_entry.feature +3 -3
  38. data/features/switch_event/delete_forward_entry.feature +3 -3
  39. data/features/switch_event/dump_forward_entries.feature +2 -2
  40. data/features/switch_event/set_forward_entries.feature +2 -2
  41. data/features/trema_commands/dump_flows.feature +1 -0
  42. data/features/trema_commands/help.feature +1 -0
  43. data/features/trema_commands/help_option.feature +1 -0
  44. data/features/trema_commands/kill.feature +1 -0
  45. data/features/trema_commands/killall.feature +1 -0
  46. data/features/trema_commands/port_down.feature +1 -0
  47. data/features/trema_commands/port_up.feature +1 -0
  48. data/features/trema_commands/reset_stats.feature +1 -0
  49. data/features/trema_commands/run.feature +1 -0
  50. data/features/trema_commands/send_packets.feature +2 -1
  51. data/features/trema_commands/show_stats.feature +1 -0
  52. data/features/trema_commands/up.feature +1 -0
  53. data/features/trema_commands/version.feature +1 -0
  54. data/features/trema_commands/version_option.feature +1 -0
  55. data/rubocop-todo.yml +159 -0
  56. data/ruby/blocker.rb +15 -17
  57. data/ruby/extconf.rb +19 -19
  58. data/ruby/sub-process.rb +29 -29
  59. data/ruby/trema/aggregate-stats-reply.rb +2 -2
  60. data/ruby/trema/app.rb +13 -13
  61. data/ruby/trema/cli.rb +45 -45
  62. data/ruby/trema/command.rb +14 -14
  63. data/ruby/trema/command/dump_flows.rb +5 -5
  64. data/ruby/trema/command/kill.rb +13 -13
  65. data/ruby/trema/command/killall.rb +1 -1
  66. data/ruby/trema/command/netns.rb +3 -3
  67. data/ruby/trema/command/port_down.rb +7 -7
  68. data/ruby/trema/command/port_up.rb +7 -7
  69. data/ruby/trema/command/reset_stats.rb +6 -6
  70. data/ruby/trema/command/ruby.rb +2 -2
  71. data/ruby/trema/command/run.rb +23 -23
  72. data/ruby/trema/command/send_packets.rb +9 -9
  73. data/ruby/trema/command/shell.rb +14 -16
  74. data/ruby/trema/command/show_stats.rb +9 -9
  75. data/ruby/trema/command/up.rb +4 -4
  76. data/ruby/trema/command/version.rb +1 -1
  77. data/ruby/trema/controller.rb +10 -10
  78. data/ruby/trema/custom-switch.rb +4 -4
  79. data/ruby/trema/daemon.rb +21 -21
  80. data/ruby/trema/desc-stats-reply.rb +2 -2
  81. data/ruby/trema/dsl.rb +5 -5
  82. data/ruby/trema/dsl/configuration.rb +7 -7
  83. data/ruby/trema/dsl/context.rb +10 -10
  84. data/ruby/trema/dsl/custom-switch.rb +3 -3
  85. data/ruby/trema/dsl/link.rb +2 -2
  86. data/ruby/trema/dsl/netns.rb +9 -9
  87. data/ruby/trema/dsl/parser.rb +14 -14
  88. data/ruby/trema/dsl/rswitch.rb +3 -3
  89. data/ruby/trema/dsl/run.rb +4 -4
  90. data/ruby/trema/dsl/runner.rb +20 -20
  91. data/ruby/trema/dsl/stanza.rb +5 -5
  92. data/ruby/trema/dsl/switch.rb +14 -14
  93. data/ruby/trema/dsl/syntax.rb +54 -54
  94. data/ruby/trema/dsl/vhost.rb +9 -9
  95. data/ruby/trema/dsl/vswitch.rb +4 -4
  96. data/ruby/trema/enqueue.rb +11 -11
  97. data/ruby/trema/exact-match.rb +1 -1
  98. data/ruby/trema/executables.rb +19 -19
  99. data/ruby/trema/flow-stats-reply.rb +2 -2
  100. data/ruby/trema/flow.rb +8 -8
  101. data/ruby/trema/hardware-switch.rb +2 -2
  102. data/ruby/trema/host.rb +18 -18
  103. data/ruby/trema/link.rb +9 -9
  104. data/ruby/trema/mac.rb +1 -5
  105. data/ruby/trema/match.c +0 -1
  106. data/ruby/trema/monkey-patch/integer.rb +3 -3
  107. data/ruby/trema/monkey-patch/integer/base-conversions.rb +1 -1
  108. data/ruby/trema/monkey-patch/integer/ranges.rb +2 -2
  109. data/ruby/trema/monkey-patch/integer/validators.rb +1 -1
  110. data/ruby/trema/monkey-patch/module.rb +2 -2
  111. data/ruby/trema/monkey-patch/module/class-method.rb +2 -2
  112. data/ruby/trema/monkey-patch/module/deprecation.rb +1 -1
  113. data/ruby/trema/monkey-patch/string.rb +1 -1
  114. data/ruby/trema/monkey-patch/string/inflectors.rb +7 -7
  115. data/ruby/trema/netns.rb +6 -6
  116. data/ruby/trema/network-component.rb +7 -7
  117. data/ruby/trema/ofctl.rb +13 -13
  118. data/ruby/trema/open-vswitch.rb +25 -25
  119. data/ruby/trema/openflow-switch.rb +1 -1
  120. data/ruby/trema/ordered-hash.rb +8 -8
  121. data/ruby/trema/packet-in.c +0 -1
  122. data/ruby/trema/packet-queue.rb +8 -8
  123. data/ruby/trema/packetin-filter.rb +9 -9
  124. data/ruby/trema/path.rb +32 -32
  125. data/ruby/trema/phost.rb +5 -5
  126. data/ruby/trema/port-mod.c +0 -1
  127. data/ruby/trema/port-stats-reply.rb +2 -2
  128. data/ruby/trema/port-status-add.rb +2 -2
  129. data/ruby/trema/port-status-delete.rb +2 -2
  130. data/ruby/trema/port-status-modify.rb +2 -2
  131. data/ruby/trema/port.c +0 -1
  132. data/ruby/trema/process.rb +7 -7
  133. data/ruby/trema/queue-stats-reply.rb +2 -2
  134. data/ruby/trema/ruby-switch.rb +6 -6
  135. data/ruby/trema/send-out-port.rb +11 -11
  136. data/ruby/trema/set-eth-addr.rb +5 -5
  137. data/ruby/trema/set-eth-dst-addr.rb +1 -1
  138. data/ruby/trema/set-eth-src-addr.rb +1 -1
  139. data/ruby/trema/set-ip-addr.rb +6 -6
  140. data/ruby/trema/set-ip-dst-addr.rb +1 -1
  141. data/ruby/trema/set-ip-src-addr.rb +1 -1
  142. data/ruby/trema/set-ip-tos.rb +6 -6
  143. data/ruby/trema/set-transport-dst-port.rb +2 -2
  144. data/ruby/trema/set-transport-port.rb +7 -7
  145. data/ruby/trema/set-transport-src-port.rb +3 -3
  146. data/ruby/trema/set-vlan-priority.rb +6 -6
  147. data/ruby/trema/set-vlan-vid.rb +6 -6
  148. data/ruby/trema/shell.rb +10 -10
  149. data/ruby/trema/shell/down.rb +3 -3
  150. data/ruby/trema/shell/killall.rb +1 -1
  151. data/ruby/trema/shell/link.rb +14 -14
  152. data/ruby/trema/shell/reset_stats.rb +6 -6
  153. data/ruby/trema/shell/run.rb +7 -7
  154. data/ruby/trema/shell/send_packets.rb +3 -3
  155. data/ruby/trema/shell/show_stats.rb +7 -7
  156. data/ruby/trema/shell/up.rb +5 -5
  157. data/ruby/trema/shell/vhost.rb +4 -4
  158. data/ruby/trema/shell/vswitch.rb +7 -7
  159. data/ruby/trema/stats-helper.rb +3 -3
  160. data/ruby/trema/stats-reply.c +0 -1
  161. data/ruby/trema/strip-vlan-header.rb +1 -1
  162. data/ruby/trema/switch-daemon.rb +9 -9
  163. data/ruby/trema/switch-manager.rb +9 -9
  164. data/ruby/trema/switch.rb +7 -7
  165. data/ruby/trema/table-stats-reply.rb +2 -2
  166. data/ruby/trema/timers.rb +12 -12
  167. data/ruby/trema/trema.c +0 -1
  168. data/ruby/trema/tremashark.rb +1 -1
  169. data/ruby/trema/util.rb +25 -27
  170. data/ruby/trema/vendor-action.rb +10 -10
  171. data/ruby/trema/vendor-stats-reply.rb +2 -2
  172. data/ruby/trema/version.rb +1 -1
  173. data/spec/spec_helper.rb +50 -52
  174. data/spec/support/action.rb +9 -12
  175. data/spec/support/mandatory-option.rb +15 -18
  176. data/spec/support/matchers/constant.rb +7 -7
  177. data/spec/support/openflow-message.rb +76 -79
  178. data/spec/support/port-status.rb +7 -10
  179. data/spec/trema/app_spec.rb +27 -27
  180. data/spec/trema/barrier-reply_spec.rb +10 -10
  181. data/spec/trema/barrier-request_spec.rb +35 -35
  182. data/spec/trema/cli_spec.rb +63 -63
  183. data/spec/trema/controller_spec.rb +3 -3
  184. data/spec/trema/default-logger_spec.rb +4 -4
  185. data/spec/trema/dsl/configuration_spec.rb +47 -47
  186. data/spec/trema/dsl/link_spec.rb +11 -11
  187. data/spec/trema/dsl/run_spec.rb +19 -19
  188. data/spec/trema/dsl/runner_spec.rb +91 -91
  189. data/spec/trema/dsl/switch_spec.rb +16 -16
  190. data/spec/trema/dsl/syntax_spec.rb +22 -22
  191. data/spec/trema/dsl/vhost_spec.rb +37 -37
  192. data/spec/trema/dsl/vswitch_spec.rb +21 -21
  193. data/spec/trema/echo-reply_spec.rb +29 -29
  194. data/spec/trema/echo-request_spec.rb +54 -54
  195. data/spec/trema/enqueue_spec.rb +25 -25
  196. data/spec/trema/error_spec.rb +30 -30
  197. data/spec/trema/executables_spec.rb +20 -20
  198. data/spec/trema/features-reply_spec.rb +41 -41
  199. data/spec/trema/features-request_spec.rb +35 -35
  200. data/spec/trema/flow-mod_spec.rb +32 -32
  201. data/spec/trema/flow-removed_spec.rb +62 -62
  202. data/spec/trema/get-config-reply_spec.rb +14 -12
  203. data/spec/trema/get-config-request_spec.rb +35 -35
  204. data/spec/trema/hardware-switch_spec.rb +12 -12
  205. data/spec/trema/hello_spec.rb +17 -17
  206. data/spec/trema/host_spec.rb +71 -71
  207. data/spec/trema/link_spec.rb +13 -13
  208. data/spec/trema/list-switches-reply_spec.rb +10 -10
  209. data/spec/trema/match_spec.rb +41 -41
  210. data/spec/trema/open-vswitch_spec.rb +45 -45
  211. data/spec/trema/openflow-error_spec.rb +67 -65
  212. data/spec/trema/packet-in_spec.rb +450 -446
  213. data/spec/trema/packet-out_spec.rb +42 -42
  214. data/spec/trema/packetin-filter_spec.rb +5 -5
  215. data/spec/trema/port-mod_spec.rb +32 -32
  216. data/spec/trema/port-status-add_spec.rb +3 -3
  217. data/spec/trema/port-status-delete_spec.rb +3 -3
  218. data/spec/trema/port-status-modify_spec.rb +16 -16
  219. data/spec/trema/port-status_spec.rb +2 -2
  220. data/spec/trema/port_spec.rb +21 -21
  221. data/spec/trema/process_spec.rb +22 -22
  222. data/spec/trema/queue-get-config-reply_spec.rb +21 -20
  223. data/spec/trema/queue-get-config-request_spec.rb +24 -24
  224. data/spec/trema/send-out-port_spec.rb +42 -42
  225. data/spec/trema/set-config_spec.rb +31 -31
  226. data/spec/trema/set-eth-addr_spec.rb +21 -21
  227. data/spec/trema/set-ip-addr_spec.rb +29 -29
  228. data/spec/trema/set-ip-tos_spec.rb +26 -26
  229. data/spec/trema/set-transport-dst-port_spec.rb +22 -22
  230. data/spec/trema/set-transport-src-port_spec.rb +22 -22
  231. data/spec/trema/set-vlan-priority_spec.rb +23 -23
  232. data/spec/trema/set-vlan-vid_spec.rb +23 -23
  233. data/spec/trema/shell/vhost_spec.rb +21 -21
  234. data/spec/trema/shell/vswitch_spec.rb +30 -30
  235. data/spec/trema/stats-reply_spec.rb +183 -173
  236. data/spec/trema/stats-request_spec.rb +66 -66
  237. data/spec/trema/strip-vlan-header_spec.rb +11 -11
  238. data/spec/trema/switch-daemon_spec.rb +34 -34
  239. data/spec/trema/switch-disconnected_spec.rb +17 -17
  240. data/spec/trema/switch-manager_spec.rb +6 -6
  241. data/spec/trema/tremashark_spec.rb +4 -4
  242. data/spec/trema/util_spec.rb +35 -35
  243. data/spec/trema/vendor-action_spec.rb +26 -26
  244. data/spec/trema/vendor_spec.rb +27 -27
  245. data/spec/trema_spec.rb +2 -2
  246. data/src/examples/cbench_switch/cbench-switch.rb +3 -3
  247. data/src/examples/dumper/dumper.rb +31 -31
  248. data/src/examples/hello_trema/hello-trema.rb +2 -2
  249. data/src/examples/learning_switch/fdb.rb +14 -14
  250. data/src/examples/learning_switch/learning-switch.rb +12 -10
  251. data/src/examples/learning_switch/learning_switch.c +22 -39
  252. data/src/examples/list_switches/list-switches.rb +3 -3
  253. data/src/examples/match_compare/match-compare.rb +20 -20
  254. data/src/examples/multi_learning_switch/multi-learning-switch.rb +12 -12
  255. data/src/examples/openflow_message/echo.rb +4 -4
  256. data/src/examples/openflow_message/example.rb +7 -7
  257. data/src/examples/openflow_message/features-request.rb +31 -31
  258. data/src/examples/openflow_message/hello.rb +2 -2
  259. data/src/examples/openflow_message/set-config.rb +4 -4
  260. data/src/examples/openflow_message/vendor-action.rb +3 -3
  261. data/src/examples/openflow_message/vendor-stats-request.rb +9 -9
  262. data/src/examples/packet_in/packet-in.rb +2 -2
  263. data/src/examples/patch_panel/patch-panel.rb +9 -9
  264. data/src/examples/repeater_hub/repeater-hub.rb +4 -4
  265. data/src/examples/repeater_hub/repeater-hub_spec.rb +65 -65
  266. data/src/examples/simple_router/arp-table.rb +7 -7
  267. data/src/examples/simple_router/interface.rb +10 -10
  268. data/src/examples/simple_router/routing-table.rb +4 -4
  269. data/src/examples/simple_router/simple-router.rb +3 -3
  270. data/src/examples/switch_info/switch-info.rb +9 -9
  271. data/src/examples/switch_monitor/switch-monitor.rb +4 -4
  272. data/src/examples/traffic_monitor/counter.rb +6 -6
  273. data/src/examples/traffic_monitor/fdb.rb +4 -4
  274. data/src/examples/traffic_monitor/traffic-monitor.rb +12 -12
  275. data/src/examples/transparent_firewall/README.md +61 -0
  276. data/src/examples/transparent_firewall/aggregated-delegated-afrinic.txt +713 -0
  277. data/src/examples/transparent_firewall/aggregated-delegated-apnic.txt +3440 -0
  278. data/src/examples/transparent_firewall/aggregated-delegated-arin.txt +11342 -0
  279. data/src/examples/transparent_firewall/aggregated-delegated-lacnic.txt +1937 -0
  280. data/src/examples/transparent_firewall/aggregated-delegated-ripencc.txt +7329 -0
  281. data/src/examples/transparent_firewall/block-rfc1918.rb +86 -0
  282. data/src/examples/transparent_firewall/pass-delegated.rb +178 -0
  283. data/src/examples/transparent_firewall/regen_aggregated.sh +53 -0
  284. data/src/examples/transparent_firewall/stats-to-cidrs.rb +59 -0
  285. data/src/lib/messenger.c +14 -5
  286. data/src/lib/openflow_message.c +0 -5
  287. data/tasks/rubocop.rake +22 -0
  288. data/trema +1 -1
  289. data/trema-config +1 -1
  290. data/trema.gemspec +22 -22
  291. metadata +30 -16
@@ -0,0 +1,86 @@
1
+ #
2
+ # Copyright (C) 2014 Denis Ovsienko
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
+ # A sample transparent firewall, see README.md for more information.
18
+ class BlockRFC1918 < Controller
19
+ PORTS = {
20
+ outside: 1,
21
+ inside: 2,
22
+ inspect: 3
23
+ }
24
+
25
+ PREFIXES = ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'].map do |each|
26
+ Pio::IPv4Address.new each
27
+ end
28
+
29
+ def switch_ready(dpid)
30
+ if @dpid
31
+ info "#{dpid.to_hex}: ignored"
32
+ return
33
+ end
34
+ @dpid = dpid
35
+ info "#{@dpid.to_hex}: connected"
36
+ start_loading
37
+ end
38
+
39
+ def switch_disconnected(dpid)
40
+ return if @dpid != dpid
41
+ info "#{@dpid.to_hex}: disconnected"
42
+ @dpid = nil
43
+ end
44
+
45
+ def barrier_reply(dpid, message)
46
+ return if dpid != @dpid
47
+ info "#{@dpid.to_hex}: loading finished"
48
+ end
49
+
50
+ private
51
+
52
+ def start_loading
53
+ PREFIXES.each do |each|
54
+ block_prefix_on_port(each, PORTS[:inside], 5000)
55
+ block_prefix_on_port(each, PORTS[:outside], 4000)
56
+ end
57
+ install_postamble(1500)
58
+ send_message(@dpid, BarrierRequest.new)
59
+ end
60
+
61
+ def block_prefix_on_port(prefix, port_number, priority)
62
+ send_flow_mod_add(
63
+ @dpid,
64
+ priority: priority + 100,
65
+ match: Match.new(in_port: port_number, dl_type: 0x0800, nw_src: prefix),
66
+ actions: SendOutPort.new(PORTS[:inspect]))
67
+ send_flow_mod_add(
68
+ @dpid,
69
+ priority: priority,
70
+ match: Match.new(in_port: port_number, dl_type: 0x0800, nw_dst: prefix),
71
+ actions: SendOutPort.new(PORTS[:inspect]))
72
+ end
73
+
74
+ def install_postamble(priority)
75
+ send_flow_mod_add(
76
+ @dpid,
77
+ priority: priority + 100,
78
+ match: Match.new(in_port: PORTS[:inside]),
79
+ actions: SendOutPort.new(PORTS[:outside]))
80
+ send_flow_mod_add(
81
+ @dpid,
82
+ priority: priority,
83
+ match: Match.new(in_port: PORTS[:outside]),
84
+ actions: SendOutPort.new(PORTS[:inside]))
85
+ end
86
+ end
@@ -0,0 +1,178 @@
1
+ #
2
+ # Copyright (C) 2014 Denis Ovsienko
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
+ # A sample transparent firewall, see README.md for more information.
18
+ class PassDelegated < Controller
19
+ PORTS = {
20
+ outside: 1,
21
+ inside: 2,
22
+ inspect: 3
23
+ }
24
+
25
+ PRIORITIES = {
26
+ bypass: 65_000,
27
+ prefix: 64_000,
28
+ inspect: 1000,
29
+ non_ipv4: 900
30
+ }
31
+
32
+ PREFIX_FILES = %w(afrinic apnic arin lacnic ripencc).map do |each|
33
+ "aggregated-delegated-#{each}.txt"
34
+ end
35
+
36
+ add_periodic_timer_event :request_flow_stats, 30
37
+
38
+ def start
39
+ @prefixes = PREFIX_FILES.reduce([]) do |result, each|
40
+ data = IO.readlines(File.join(File.dirname(__FILE__), each))
41
+ info "#{each}: #{data.size} prefix(es)"
42
+ result + data
43
+ end
44
+ end
45
+
46
+ def switch_ready(dpid)
47
+ if @dpid
48
+ info "#{dpid.to_hex}: ignored"
49
+ return
50
+ end
51
+ @dpid = dpid
52
+ info "#{@dpid.to_hex}: connected"
53
+ start_loading
54
+ end
55
+
56
+ def switch_disconnected(dpid)
57
+ return if @dpid != dpid
58
+ info "#{@dpid.to_hex}: disconnected"
59
+ @dpid = nil
60
+ end
61
+
62
+ def barrier_reply(dpid, message)
63
+ return if dpid != @dpid
64
+ case @state
65
+ when :loading then finish_loading
66
+ when :running then dump_flow_stats
67
+ else fail
68
+ end
69
+ end
70
+
71
+ def stats_reply(dpid, message)
72
+ return unless dpid == @dpid && message.type == StatsReply::OFPST_FLOW
73
+ message.stats.each do |each|
74
+ case each.priority
75
+ when PRIORITIES[:prefix]
76
+ @stats.push each if each.byte_count > 0
77
+ when PRIORITIES[:inspect]
78
+ @denied_bytes = each.byte_count
79
+ end
80
+ end
81
+ end
82
+
83
+ private
84
+
85
+ def start_loading
86
+ install_preamble_and_bypass
87
+ install_prefixes
88
+ install_postamble
89
+ @state = :loading
90
+ @loading_started = Time.now
91
+ send_message(@dpid, BarrierRequest.new)
92
+ end
93
+
94
+ # All flows in place, safe to remove bypass.
95
+ def finish_loading
96
+ send_flow_mod_delete(
97
+ @dpid,
98
+ strict: true,
99
+ priority: PRIORITIES[:bypass],
100
+ match: Match.new(in_port: PORTS[:outside]))
101
+ info '%s: bypass OFF', @dpid.to_hex
102
+ info('%s: loading finished in %.2f second(s)',
103
+ @dpid.to_hex, Time.now - @loading_started)
104
+ @denied_bytes = 0
105
+ @state = :running
106
+ end
107
+
108
+ def install_preamble_and_bypass
109
+ send_flow_mod_add(
110
+ @dpid,
111
+ priority: PRIORITIES[:bypass],
112
+ match: Match.new(in_port: PORTS[:inside]),
113
+ actions: SendOutPort.new(PORTS[:outside]))
114
+ send_flow_mod_add(
115
+ @dpid, priority: PRIORITIES[:bypass],
116
+ match: Match.new(in_port: PORTS[:outside]),
117
+ actions: SendOutPort.new(PORTS[:inside]))
118
+ info "#{@dpid.to_hex}: bypass ON"
119
+ end
120
+
121
+ def install_prefixes
122
+ info "#{@dpid.to_hex}: loading started"
123
+ @prefixes.each do |each|
124
+ send_flow_mod_add(
125
+ @dpid, priority: PRIORITIES[:prefix],
126
+ match: Match.new(in_port: PORTS[:outside],
127
+ dl_type: 0x0800,
128
+ nw_src: Pio::IPv4Address.new(each)),
129
+ actions: SendOutPort.new(PORTS[:inside]))
130
+ end
131
+ end
132
+
133
+ # Deny any other IPv4 and permit non-IPv4 traffic.
134
+ def install_postamble
135
+ send_flow_mod_add(
136
+ @dpid,
137
+ priority: PRIORITIES[:inspect],
138
+ match: Match.new(in_port: PORTS[:outside], dl_type: 0x0800),
139
+ actions: SendOutPort.new(PORTS[:inspect]))
140
+ send_flow_mod_add(
141
+ @dpid,
142
+ priority: PRIORITIES[:non_ipv4],
143
+ match: Match.new(in_port: PORTS[:outside]),
144
+ actions: SendOutPort.new(PORTS[:inside]))
145
+ end
146
+
147
+ def dump_top_flows
148
+ return unless @stats.size > 0
149
+ info 'top-10 permitted source prefixes by bytes'
150
+ @stats.first(10).each do |each|
151
+ info('%15s/%-2u %u',
152
+ each.match.nw_src.to_s,
153
+ each.match.nw_src.prefixlen,
154
+ each.byte_count)
155
+ end
156
+ end
157
+
158
+ def dump_flow_stats
159
+ @stats.sort! do |a, b|
160
+ 1 if a.byte_count < b.byte_count
161
+ -1 if a.byte_count > b.byte_count
162
+ 0
163
+ end
164
+ dump_top_flows
165
+ info "total denied bytes: #{@denied_bytes}" if @denied_bytes > 0
166
+ @stats = []
167
+ end
168
+
169
+ # Interested in flows with and without IPv4 prefixes.
170
+ def request_flow_stats
171
+ return if @dpid.nil? || @state != :running
172
+ @stats = []
173
+ send_message(
174
+ @dpid,
175
+ FlowStatsRequest.new(match: Match.new(in_port: PORTS[:outside])))
176
+ send_message @dpid, BarrierRequest.new
177
+ end
178
+ end
@@ -0,0 +1,53 @@
1
+ #!/bin/sh
2
+
3
+ # This helper script fetches each RIR's current delegation statistics and
4
+ # produces an aggregated CIDR version of the data.
5
+
6
+ usage()
7
+ {
8
+ echo "Usage: $0 [-f]"
9
+ echo " -f force data download"
10
+ exit 1
11
+ }
12
+
13
+ [ $# -eq 0 -o $# -eq 1 ] || usage
14
+
15
+ case $# in
16
+ 0) FORCE=0 ;;
17
+ 1)
18
+ case "$1" in
19
+ -f) FORCE=1 ;;
20
+ *) usage ;;
21
+ esac
22
+ ;;
23
+ *) usage ;;
24
+ esac
25
+
26
+ if ! which aggregate >/dev/null 2>&1; then
27
+ echo 'Error: "aggregate" is not available!'
28
+ exit 2
29
+ fi
30
+ if which lftpget >/dev/null 2>&1; then
31
+ FETCH=lftpget
32
+ elif which wget >/dev/null 2>&1; then
33
+ FETCH=wget
34
+ elif which curl >/dev/null 2>&1; then
35
+ FETCH=curl
36
+ else
37
+ echo 'Error: neither "lftpget" nor "wget" nor "curl" is available!'
38
+ exit 2
39
+ fi
40
+
41
+ for rir in afrinic apnic arin lacnic ripencc; do
42
+ # Fetch NROESF, ARIN has discontinued RIRSEF.
43
+ dfile=delegated-$rir-extended-latest
44
+ afile=aggregated-delegated-$rir.txt
45
+ if [ ! -s $dfile -o $FORCE -eq 1 ]; then
46
+ [ -s $dfile ] && rm -f $dfile
47
+ lftpget ftp://ftp.ripe.net/pub/stats/$rir/$dfile
48
+ fi
49
+ if [ ! -s $afile -o $dfile -nt $afile ]; then
50
+ cat $dfile | ./stats-to-cidrs.rb | aggregate > $afile
51
+ wc -l $afile
52
+ fi
53
+ done
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # This helper scripts translates stdin in RIR Statistics Exchange Format [1]
4
+ # or NRO Extended Stats Format [2] into stdout in "dotted-quad/masklen" CIDR
5
+ # format (one CIDR block per line). It processes only assigned/allocated IPv4
6
+ # address ranges and produces one or more CIDR blocks for each range.
7
+ #
8
+ # 1: ftp://ftp.ripe.net/ripe/stats/RIR-Statistics-Exchange-Format.txt
9
+ # 2: https://www.arin.net/knowledge/statistics/nro_extended_stats_format.pdf
10
+ #
11
+ # Copyright (C) 2013 Denis Ovsienko
12
+ #
13
+ # This program is free software; you can redistribute it and/or modify
14
+ # it under the terms of the GNU General Public License, version 2, as
15
+ # published by the Free Software Foundation.
16
+ #
17
+ # This program is distributed in the hope that it will be useful,
18
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
+ # GNU General Public License for more details.
21
+ #
22
+ # You should have received a copy of the GNU General Public License along
23
+ # with this program; if not, write to the Free Software Foundation, Inc.,
24
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25
+
26
+ # "gem install ipaddress" or "yum install rubygem-ipaddress"
27
+ require 'ipaddress'
28
+
29
+ def max_pow2_denominating(x)
30
+ denominators =
31
+ { 2**24 => 24, 2**23 => 23, 2**22 => 22, 2**21 => 21, 2**20 => 20,
32
+ 2**19 => 19, 2**18 => 18, 2**17 => 17, 2**16 => 16, 2**15 => 15,
33
+ 2**14 => 14, 2**13 => 13, 2**12 => 12, 2**11 => 11, 2**10 => 10,
34
+ 2**9 => 9, 2**8 => 8, 2**7 => 7, 2**6 => 6, 2**5 => 5, 2**4 => 4,
35
+ 2**3 => 3 }
36
+ denominators.each do |pow, index|
37
+ return index if x % pow == 0
38
+ end
39
+ fail(ArgumentError)
40
+ end
41
+
42
+ def max_pow2_not_greater(x)
43
+ Integer(Math.log2(x))
44
+ end
45
+
46
+ re = /\|ipv4\|([\d\.]+)\|(\d+)\|\d+\|(?:allocated|assigned)/
47
+ ARGF.each_line do |line|
48
+ next if (match = re.match(line)).nil?
49
+ start = IPAddress::IPv4.new(match[1]).u32
50
+ count = Integer(match[2])
51
+ fail(ArgumentError, '/8 is the largest allowed prefix') if count > 2**24
52
+ while count > 0
53
+ idx2 = [max_pow2_denominating(start), max_pow2_not_greater(count)].min
54
+ fail(ArgumentError, '/29 is the smallest allowed prefix') if idx2 < 3
55
+ puts(IPAddress::IPv4.parse_u32(start, 32 - idx2).to_string)
56
+ start += 2**idx2
57
+ count -= 2**idx2
58
+ end
59
+ end
@@ -192,7 +192,8 @@ typedef struct send_queue {
192
192
 
193
193
  #define MESSENGER_RECV_BUFFER 100000
194
194
  static const uint32_t messenger_send_queue_length = MESSENGER_RECV_BUFFER * 4;
195
- static const uint32_t messenger_send_length_for_flush = MESSENGER_RECV_BUFFER;
195
+ static const uint32_t messenger_flush_limit_length = MESSENGER_RECV_BUFFER * 2;
196
+ static const uint32_t messenger_flush_length = MESSENGER_RECV_BUFFER / 4;
196
197
  static const uint32_t messenger_bucket_size = MESSENGER_RECV_BUFFER;
197
198
  static const uint32_t messenger_recv_queue_length = MESSENGER_RECV_BUFFER * 2;
198
199
  static const uint32_t messenger_recv_queue_reserved = MESSENGER_RECV_BUFFER;
@@ -885,10 +886,6 @@ send_queue_connect( send_queue *sq ) {
885
886
  set_fd_handler( sq->server_socket, on_send_read, sq, on_send_write, sq );
886
887
  set_readable( sq->server_socket, true );
887
888
 
888
- if ( sq->buffer != NULL && sq->buffer->data_length >= sizeof( message_header ) ) {
889
- set_writable( sq->server_socket, true );
890
- }
891
-
892
889
  debug( "Connection established ( service_name = %s, sun_path = %s, fd = %d ).",
893
890
  sq->service_name, sq->server_addr.sun_path, sq->server_socket );
894
891
 
@@ -899,6 +896,14 @@ send_queue_connect( send_queue *sq ) {
899
896
 
900
897
  send_dump_message( MESSENGER_DUMP_SEND_CONNECTED, sq->service_name, NULL, 0 );
901
898
 
899
+ if ( sq->buffer != NULL && sq->buffer->data_length >= sizeof( message_header ) ) {
900
+ set_writable( sq->server_socket, true );
901
+ if ( sq->buffer->data_length >= messenger_flush_length &&
902
+ sq->buffer->data_length < messenger_flush_limit_length ) {
903
+ on_send_write( sq->server_socket, sq );
904
+ }
905
+ }
906
+
902
907
  return 1;
903
908
  }
904
909
 
@@ -1101,6 +1106,10 @@ push_message_to_send_queue( const char *service_name, const uint8_t message_type
1101
1106
  }
1102
1107
 
1103
1108
  set_writable( sq->server_socket, true );
1109
+ if ( sq->buffer->data_length >= messenger_flush_length &&
1110
+ sq->buffer->data_length < messenger_flush_limit_length ) {
1111
+ on_send_write( sq->server_socket, sq );
1112
+ }
1104
1113
 
1105
1114
  return true;
1106
1115
  }
@@ -2487,11 +2487,6 @@ validate_port_stats_request( const buffer *message ) {
2487
2487
 
2488
2488
  port_stats_request = ( struct ofp_port_stats_request * ) stats_request->body;
2489
2489
 
2490
- ret = validate_phy_port_no( ntohs( port_stats_request->port_no ) );
2491
- if ( ret < 0 ) {
2492
- return ret;
2493
- }
2494
-
2495
2490
  if ( ntohs( port_stats_request->port_no ) > OFPP_MAX
2496
2491
  && ntohs( port_stats_request->port_no ) != OFPP_NONE
2497
2492
  && ntohs( port_stats_request->port_no ) != OFPP_LOCAL ) {
@@ -0,0 +1,22 @@
1
+ begin
2
+ require 'rubocop/rake_task'
3
+ Rubocop::RakeTask.new do |task|
4
+ task.patterns =
5
+ [
6
+ 'Gemfile',
7
+ 'Rakefile',
8
+ 'bin/*',
9
+ 'cruise.rb',
10
+ 'features/**/*.rb',
11
+ 'ruby/**/*.rb',
12
+ 'spec/**/*.rb',
13
+ 'src/**/*.rb',
14
+ 'tasks/*.rake',
15
+ 'trema.gemspec'
16
+ ]
17
+ end
18
+ rescue LoadError
19
+ task :rubocop do
20
+ $stderr.puts 'Rubocop is disabled'
21
+ end
22
+ end