trema 0.4.7 → 0.4.8

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 (718) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +33 -54
  3. data/.hound.yml +3 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +17 -1
  6. data/.travis.yml +14 -18
  7. data/CHANGELOG.md +10 -0
  8. data/Gemfile +1 -26
  9. data/README.md +25 -241
  10. data/Rakefile +4 -1056
  11. data/bin/.gitignore +3 -0
  12. data/bin/trema +163 -237
  13. data/features/cleanup_on_failure.feature +118 -0
  14. data/features/logging.feature +73 -0
  15. data/features/open_flow13.feature +21 -0
  16. data/features/step_definitions/.gitignore +35 -0
  17. data/features/step_definitions/.rubocop.yml +5 -0
  18. data/features/step_definitions/.travis.yml +19 -0
  19. data/features/step_definitions/Gemfile +9 -0
  20. data/features/step_definitions/Guardfile +4 -0
  21. data/features/step_definitions/LICENSE +675 -0
  22. data/features/step_definitions/README.md +7 -0
  23. data/features/step_definitions/Rakefile +10 -0
  24. data/features/step_definitions/show_stats_steps.rb +56 -0
  25. data/features/step_definitions/virtual_link_steps.rb +8 -0
  26. data/features/support/env.rb +0 -73
  27. data/features/support/hooks.rb +6 -50
  28. data/features/trema_delete_link.feature +30 -0
  29. data/features/trema_killall.feature +56 -0
  30. data/features/trema_run.feature +47 -0
  31. data/features/trema_start.feature +73 -0
  32. data/features/trema_stop.feature +50 -0
  33. data/lib/trema.rb +4 -0
  34. data/lib/trema/command.rb +184 -0
  35. data/lib/trema/controller.rb +289 -0
  36. data/lib/trema/dirs.rb +14 -0
  37. data/lib/trema/drb.rb +32 -0
  38. data/lib/trema/logger.rb +63 -0
  39. data/lib/trema/monkey_patch/integer.rb +8 -0
  40. data/lib/trema/monkey_patch/integer/base_conversions.rb +12 -0
  41. data/lib/trema/monkey_patch/integer/durations.rb +12 -0
  42. data/lib/trema/switch.rb +83 -0
  43. data/lib/trema/version.rb +5 -0
  44. data/spec/spec_helper.rb +9 -178
  45. data/spec/trema/controller_spec.rb +4 -53
  46. data/tasks/.gitignore +34 -0
  47. data/tasks/LICENSE +675 -0
  48. data/tasks/README.md +6 -0
  49. data/tasks/cucumber.rake +14 -0
  50. data/tasks/flay.rake +15 -0
  51. data/tasks/flog.rake +25 -0
  52. data/tasks/gem.rake +15 -0
  53. data/tasks/reek.rake +11 -0
  54. data/tasks/relish.rake +8 -0
  55. data/tasks/rspec.rake +8 -0
  56. data/tasks/rubocop.rake +2 -16
  57. data/tasks/yard.rake +11 -0
  58. data/trema.gemspec +24 -23
  59. metadata +180 -720
  60. data/.yardopts +0 -4
  61. data/Doxyfile +0 -1679
  62. data/Guardfile +0 -14
  63. data/bin/quality +0 -31
  64. data/bin/trema-config +0 -59
  65. data/build.rb +0 -32
  66. data/cruise.rb +0 -409
  67. data/features/.nav +0 -50
  68. data/features/README.md +0 -7
  69. data/features/core/get_pid_by_trema_name.feature +0 -137
  70. data/features/core/packetin_filter.feature +0 -55
  71. data/features/core/switch_manager.feature +0 -41
  72. data/features/core/trema-config.feature +0 -55
  73. data/features/dsl/switch_port_specifier.feature +0 -15
  74. data/features/examples/dumper.feature +0 -35
  75. data/features/examples/hello_trema.feature +0 -23
  76. data/features/examples/learning_switch.feature +0 -37
  77. data/features/examples/list_switches.feature +0 -24
  78. data/features/examples/message.set_config.feature +0 -27
  79. data/features/examples/message.vendor-action.feature +0 -25
  80. data/features/examples/message.vendor-stats-request.feature +0 -20
  81. data/features/examples/multi_learning_switch.feature +0 -107
  82. data/features/examples/openflow_message.echo.feature +0 -59
  83. data/features/examples/openflow_message.features_request.feature +0 -35
  84. data/features/examples/openflow_message.hello.feature +0 -59
  85. data/features/examples/packet_in.feature +0 -33
  86. data/features/examples/packetin_filter_config.feature +0 -95
  87. data/features/examples/patch_panel.feature +0 -29
  88. data/features/examples/repeater_hub.feature +0 -52
  89. data/features/examples/switch_info.feature +0 -51
  90. data/features/examples/switch_monitor.feature +0 -35
  91. data/features/examples/transparent_firewall.feature +0 -73
  92. data/features/handlers/switch_ready.feature +0 -40
  93. data/features/step_definitions/misc_steps.rb +0 -85
  94. data/features/step_definitions/send_packets_steps.rb +0 -33
  95. data/features/step_definitions/stats_steps.rb +0 -39
  96. data/features/switch_event/C-add_forward_entry.feature +0 -114
  97. data/features/switch_event/C-delete_forward_entry.feature +0 -85
  98. data/features/switch_event/C-dump_forward_entries.feature +0 -72
  99. data/features/switch_event/C-set_forward_entries.feature +0 -77
  100. data/features/switch_event/README.md +0 -40
  101. data/features/switch_event/add_forward_entry.feature +0 -160
  102. data/features/switch_event/delete_forward_entry.feature +0 -160
  103. data/features/switch_event/dump_forward_entries.feature +0 -103
  104. data/features/switch_event/set_forward_entries.feature +0 -102
  105. data/features/trema_commands/README.md +0 -8
  106. data/features/trema_commands/dump_flows.feature +0 -41
  107. data/features/trema_commands/help.feature +0 -27
  108. data/features/trema_commands/help_option.feature +0 -20
  109. data/features/trema_commands/kill.feature +0 -56
  110. data/features/trema_commands/killall.feature +0 -32
  111. data/features/trema_commands/port_down.feature +0 -71
  112. data/features/trema_commands/port_up.feature +0 -75
  113. data/features/trema_commands/reset_stats.feature +0 -56
  114. data/features/trema_commands/run.feature +0 -56
  115. data/features/trema_commands/send_packets.feature +0 -46
  116. data/features/trema_commands/show_stats.feature +0 -66
  117. data/features/trema_commands/up.feature +0 -34
  118. data/features/trema_commands/version.feature +0 -10
  119. data/features/trema_commands/version_option.feature +0 -8
  120. data/rubocop-todo.yml +0 -159
  121. data/ruby/.gitignore +0 -4
  122. data/ruby/blocker.rb +0 -74
  123. data/ruby/extconf.rb +0 -80
  124. data/ruby/sub-process.rb +0 -289
  125. data/ruby/trema/action-common.c +0 -46
  126. data/ruby/trema/action-common.h +0 -38
  127. data/ruby/trema/action.rb +0 -33
  128. data/ruby/trema/aggregate-stats-reply.rb +0 -68
  129. data/ruby/trema/app.rb +0 -114
  130. data/ruby/trema/barrier-reply.c +0 -98
  131. data/ruby/trema/barrier-reply.h +0 -44
  132. data/ruby/trema/barrier-request.c +0 -135
  133. data/ruby/trema/barrier-request.h +0 -42
  134. data/ruby/trema/cli.rb +0 -267
  135. data/ruby/trema/command.rb +0 -41
  136. data/ruby/trema/command/dump_flows.rb +0 -43
  137. data/ruby/trema/command/kill.rb +0 -75
  138. data/ruby/trema/command/killall.rb +0 -38
  139. data/ruby/trema/command/netns.rb +0 -38
  140. data/ruby/trema/command/port_down.rb +0 -43
  141. data/ruby/trema/command/port_up.rb +0 -43
  142. data/ruby/trema/command/reset_stats.rb +0 -41
  143. data/ruby/trema/command/ruby.rb +0 -38
  144. data/ruby/trema/command/run.rb +0 -110
  145. data/ruby/trema/command/send_packets.rb +0 -46
  146. data/ruby/trema/command/shell.rb +0 -57
  147. data/ruby/trema/command/show_stats.rb +0 -65
  148. data/ruby/trema/command/up.rb +0 -44
  149. data/ruby/trema/command/version.rb +0 -35
  150. data/ruby/trema/compat.h +0 -36
  151. data/ruby/trema/controller.c +0 -691
  152. data/ruby/trema/controller.h +0 -42
  153. data/ruby/trema/controller.rb +0 -255
  154. data/ruby/trema/custom-switch.rb +0 -56
  155. data/ruby/trema/daemon.rb +0 -184
  156. data/ruby/trema/default-logger.c +0 -161
  157. data/ruby/trema/default-logger.h +0 -42
  158. data/ruby/trema/default-logger.rb +0 -29
  159. data/ruby/trema/default_openflow_channel_port.rb +0 -26
  160. data/ruby/trema/desc-stats-reply.rb +0 -75
  161. data/ruby/trema/dsl.rb +0 -32
  162. data/ruby/trema/dsl/configuration.rb +0 -145
  163. data/ruby/trema/dsl/context.rb +0 -69
  164. data/ruby/trema/dsl/custom-switch.rb +0 -44
  165. data/ruby/trema/dsl/link.rb +0 -39
  166. data/ruby/trema/dsl/netns.rb +0 -78
  167. data/ruby/trema/dsl/parser.rb +0 -70
  168. data/ruby/trema/dsl/rswitch.rb +0 -47
  169. data/ruby/trema/dsl/run.rb +0 -47
  170. data/ruby/trema/dsl/runner.rb +0 -178
  171. data/ruby/trema/dsl/stanza.rb +0 -51
  172. data/ruby/trema/dsl/switch.rb +0 -76
  173. data/ruby/trema/dsl/syntax-error.rb +0 -31
  174. data/ruby/trema/dsl/syntax.rb +0 -128
  175. data/ruby/trema/dsl/vhost.rb +0 -106
  176. data/ruby/trema/dsl/vswitch.rb +0 -45
  177. data/ruby/trema/echo-reply.c +0 -122
  178. data/ruby/trema/echo-reply.h +0 -40
  179. data/ruby/trema/echo-request.c +0 -117
  180. data/ruby/trema/echo-request.h +0 -40
  181. data/ruby/trema/echo.c +0 -99
  182. data/ruby/trema/echo.h +0 -39
  183. data/ruby/trema/enqueue.rb +0 -87
  184. data/ruby/trema/error.c +0 -262
  185. data/ruby/trema/error.h +0 -42
  186. data/ruby/trema/exact-match.rb +0 -34
  187. data/ruby/trema/executables.rb +0 -99
  188. data/ruby/trema/features-reply.c +0 -330
  189. data/ruby/trema/features-reply.h +0 -54
  190. data/ruby/trema/features-request.c +0 -134
  191. data/ruby/trema/features-request.h +0 -42
  192. data/ruby/trema/flow-mod.c +0 -150
  193. data/ruby/trema/flow-mod.h +0 -42
  194. data/ruby/trema/flow-removed.c +0 -280
  195. data/ruby/trema/flow-removed.h +0 -44
  196. data/ruby/trema/flow-stats-reply.rb +0 -107
  197. data/ruby/trema/flow.rb +0 -65
  198. data/ruby/trema/get-config-reply.c +0 -158
  199. data/ruby/trema/get-config-reply.h +0 -50
  200. data/ruby/trema/get-config-request.c +0 -136
  201. data/ruby/trema/get-config-request.h +0 -42
  202. data/ruby/trema/hardware-switch.rb +0 -86
  203. data/ruby/trema/hello.c +0 -133
  204. data/ruby/trema/hello.h +0 -42
  205. data/ruby/trema/host.rb +0 -263
  206. data/ruby/trema/link.rb +0 -177
  207. data/ruby/trema/list-switches-reply.c +0 -44
  208. data/ruby/trema/list-switches-reply.h +0 -38
  209. data/ruby/trema/mac.rb +0 -29
  210. data/ruby/trema/match.c +0 -621
  211. data/ruby/trema/match.h +0 -34
  212. data/ruby/trema/monkey-patch/integer.rb +0 -35
  213. data/ruby/trema/monkey-patch/integer/base-conversions.rb +0 -34
  214. data/ruby/trema/monkey-patch/integer/ranges.rb +0 -49
  215. data/ruby/trema/monkey-patch/integer/validators.rb +0 -36
  216. data/ruby/trema/monkey-patch/module.rb +0 -33
  217. data/ruby/trema/monkey-patch/module/class-method.rb +0 -38
  218. data/ruby/trema/monkey-patch/module/deprecation.rb +0 -39
  219. data/ruby/trema/monkey-patch/string.rb +0 -31
  220. data/ruby/trema/monkey-patch/string/inflectors.rb +0 -52
  221. data/ruby/trema/netns.rb +0 -127
  222. data/ruby/trema/network-component.rb +0 -151
  223. data/ruby/trema/ofctl.rb +0 -70
  224. data/ruby/trema/open-vswitch.rb +0 -160
  225. data/ruby/trema/openflow-error.c +0 -193
  226. data/ruby/trema/openflow-error.h +0 -51
  227. data/ruby/trema/openflow-switch.rb +0 -35
  228. data/ruby/trema/ordered-hash.rb +0 -75
  229. data/ruby/trema/packet-in.c +0 -1365
  230. data/ruby/trema/packet-in.h +0 -44
  231. data/ruby/trema/packet-queue.rb +0 -181
  232. data/ruby/trema/packetin-filter.rb +0 -124
  233. data/ruby/trema/path.rb +0 -85
  234. data/ruby/trema/phost.rb +0 -76
  235. data/ruby/trema/port-mod.c +0 -232
  236. data/ruby/trema/port-mod.h +0 -34
  237. data/ruby/trema/port-stats-reply.rb +0 -109
  238. data/ruby/trema/port-status-add.rb +0 -60
  239. data/ruby/trema/port-status-delete.rb +0 -60
  240. data/ruby/trema/port-status-modify.rb +0 -60
  241. data/ruby/trema/port-status.c +0 -192
  242. data/ruby/trema/port-status.h +0 -41
  243. data/ruby/trema/port.c +0 -398
  244. data/ruby/trema/port.h +0 -45
  245. data/ruby/trema/process.rb +0 -103
  246. data/ruby/trema/queue-get-config-reply.c +0 -205
  247. data/ruby/trema/queue-get-config-reply.h +0 -45
  248. data/ruby/trema/queue-get-config-request.c +0 -141
  249. data/ruby/trema/queue-get-config-request.h +0 -42
  250. data/ruby/trema/queue-stats-reply.rb +0 -76
  251. data/ruby/trema/ruby-switch.rb +0 -62
  252. data/ruby/trema/send-out-port.rb +0 -113
  253. data/ruby/trema/set-config.c +0 -174
  254. data/ruby/trema/set-config.h +0 -42
  255. data/ruby/trema/set-eth-addr.rb +0 -54
  256. data/ruby/trema/set-eth-dst-addr.rb +0 -52
  257. data/ruby/trema/set-eth-src-addr.rb +0 -53
  258. data/ruby/trema/set-ip-addr.rb +0 -54
  259. data/ruby/trema/set-ip-dst-addr.rb +0 -53
  260. data/ruby/trema/set-ip-src-addr.rb +0 -52
  261. data/ruby/trema/set-ip-tos.rb +0 -64
  262. data/ruby/trema/set-transport-dst-port.rb +0 -53
  263. data/ruby/trema/set-transport-port.rb +0 -53
  264. data/ruby/trema/set-transport-src-port.rb +0 -54
  265. data/ruby/trema/set-vlan-priority.rb +0 -66
  266. data/ruby/trema/set-vlan-vid.rb +0 -65
  267. data/ruby/trema/shell.rb +0 -37
  268. data/ruby/trema/shell/down.rb +0 -37
  269. data/ruby/trema/shell/killall.rb +0 -38
  270. data/ruby/trema/shell/link.rb +0 -59
  271. data/ruby/trema/shell/reset_stats.rb +0 -49
  272. data/ruby/trema/shell/run.rb +0 -67
  273. data/ruby/trema/shell/send_packets.rb +0 -40
  274. data/ruby/trema/shell/show_stats.rb +0 -47
  275. data/ruby/trema/shell/up.rb +0 -41
  276. data/ruby/trema/shell/vhost.rb +0 -42
  277. data/ruby/trema/shell/vswitch.rb +0 -47
  278. data/ruby/trema/stats-helper.rb +0 -63
  279. data/ruby/trema/stats-reply.c +0 -540
  280. data/ruby/trema/stats-reply.h +0 -51
  281. data/ruby/trema/stats-request.c +0 -715
  282. data/ruby/trema/stats-request.h +0 -40
  283. data/ruby/trema/strip-vlan-header.rb +0 -41
  284. data/ruby/trema/switch-daemon.rb +0 -90
  285. data/ruby/trema/switch-disconnected.c +0 -38
  286. data/ruby/trema/switch-disconnected.h +0 -36
  287. data/ruby/trema/switch-event.c +0 -648
  288. data/ruby/trema/switch-event.h +0 -27
  289. data/ruby/trema/switch-manager.rb +0 -119
  290. data/ruby/trema/switch.c +0 -197
  291. data/ruby/trema/switch.h +0 -40
  292. data/ruby/trema/switch.rb +0 -56
  293. data/ruby/trema/table-stats-reply.rb +0 -85
  294. data/ruby/trema/timers.rb +0 -95
  295. data/ruby/trema/trema-ruby-utils.c +0 -66
  296. data/ruby/trema/trema-ruby-utils.h +0 -42
  297. data/ruby/trema/trema.c +0 -126
  298. data/ruby/trema/tremashark.rb +0 -46
  299. data/ruby/trema/util.rb +0 -116
  300. data/ruby/trema/vendor-action.rb +0 -82
  301. data/ruby/trema/vendor-stats-reply.rb +0 -64
  302. data/ruby/trema/vendor.c +0 -230
  303. data/ruby/trema/vendor.h +0 -48
  304. data/ruby/trema/version.rb +0 -28
  305. data/spec/support/action.rb +0 -49
  306. data/spec/support/mandatory-option.rb +0 -53
  307. data/spec/support/matchers/constant.rb +0 -25
  308. data/spec/support/openflow-message.rb +0 -173
  309. data/spec/support/port-status.rb +0 -35
  310. data/spec/trema/app_spec.rb +0 -88
  311. data/spec/trema/barrier-reply_spec.rb +0 -43
  312. data/spec/trema/barrier-request_spec.rb +0 -92
  313. data/spec/trema/cli_spec.rb +0 -156
  314. data/spec/trema/default-logger_spec.rb +0 -46
  315. data/spec/trema/dsl/configuration_spec.rb +0 -120
  316. data/spec/trema/dsl/link_spec.rb +0 -50
  317. data/spec/trema/dsl/run_spec.rb +0 -72
  318. data/spec/trema/dsl/runner_spec.rb +0 -247
  319. data/spec/trema/dsl/switch_spec.rb +0 -69
  320. data/spec/trema/dsl/syntax_spec.rb +0 -110
  321. data/spec/trema/dsl/vhost_spec.rb +0 -144
  322. data/spec/trema/dsl/vswitch_spec.rb +0 -80
  323. data/spec/trema/echo-reply_spec.rb +0 -84
  324. data/spec/trema/echo-request_spec.rb +0 -128
  325. data/spec/trema/enqueue_spec.rb +0 -76
  326. data/spec/trema/error_spec.rb +0 -81
  327. data/spec/trema/executables_spec.rb +0 -54
  328. data/spec/trema/features-reply_spec.rb +0 -91
  329. data/spec/trema/features-request_spec.rb +0 -93
  330. data/spec/trema/flow-mod_spec.rb +0 -99
  331. data/spec/trema/flow-removed_spec.rb +0 -144
  332. data/spec/trema/get-config-reply_spec.rb +0 -43
  333. data/spec/trema/get-config-request_spec.rb +0 -92
  334. data/spec/trema/hardware-switch_spec.rb +0 -54
  335. data/spec/trema/hello_spec.rb +0 -63
  336. data/spec/trema/host_spec.rb +0 -191
  337. data/spec/trema/link_spec.rb +0 -62
  338. data/spec/trema/list-switches-reply_spec.rb +0 -46
  339. data/spec/trema/match_spec.rb +0 -111
  340. data/spec/trema/open-vswitch_spec.rb +0 -121
  341. data/spec/trema/openflow-error_spec.rb +0 -141
  342. data/spec/trema/packet-in_spec.rb +0 -717
  343. data/spec/trema/packet-out_spec.rb +0 -125
  344. data/spec/trema/packetin-filter_spec.rb +0 -39
  345. data/spec/trema/port-mod_spec.rb +0 -98
  346. data/spec/trema/port-status-add_spec.rb +0 -32
  347. data/spec/trema/port-status-delete_spec.rb +0 -32
  348. data/spec/trema/port-status-modify_spec.rb +0 -71
  349. data/spec/trema/port-status_spec.rb +0 -38
  350. data/spec/trema/port_spec.rb +0 -59
  351. data/spec/trema/process_spec.rb +0 -69
  352. data/spec/trema/queue-get-config-reply_spec.rb +0 -65
  353. data/spec/trema/queue-get-config-request_spec.rb +0 -67
  354. data/spec/trema/send-out-port_spec.rb +0 -106
  355. data/spec/trema/set-config_spec.rb +0 -78
  356. data/spec/trema/set-eth-addr_spec.rb +0 -62
  357. data/spec/trema/set-ip-addr_spec.rb +0 -81
  358. data/spec/trema/set-ip-tos_spec.rb +0 -70
  359. data/spec/trema/set-transport-dst-port_spec.rb +0 -65
  360. data/spec/trema/set-transport-src-port_spec.rb +0 -65
  361. data/spec/trema/set-vlan-priority_spec.rb +0 -65
  362. data/spec/trema/set-vlan-vid_spec.rb +0 -65
  363. data/spec/trema/shell/vhost_spec.rb +0 -58
  364. data/spec/trema/shell/vswitch_spec.rb +0 -87
  365. data/spec/trema/stats-reply_spec.rb +0 -363
  366. data/spec/trema/stats-request_spec.rb +0 -166
  367. data/spec/trema/strip-vlan-header_spec.rb +0 -44
  368. data/spec/trema/switch-daemon_spec.rb +0 -81
  369. data/spec/trema/switch-disconnected_spec.rb +0 -56
  370. data/spec/trema/switch-manager_spec.rb +0 -41
  371. data/spec/trema/tremashark_spec.rb +0 -39
  372. data/spec/trema/util_spec.rb +0 -88
  373. data/spec/trema/vendor-action_spec.rb +0 -75
  374. data/spec/trema/vendor_spec.rb +0 -76
  375. data/spec/trema_spec.rb +0 -94
  376. data/src/examples/cbench_switch/README +0 -21
  377. data/src/examples/cbench_switch/cbench-switch.rb +0 -38
  378. data/src/examples/cbench_switch/cbench_switch.c +0 -66
  379. data/src/examples/dumper/dumper.c +0 -362
  380. data/src/examples/dumper/dumper.conf +0 -7
  381. data/src/examples/dumper/dumper.rb +0 -195
  382. data/src/examples/hello_trema/.gitignore +0 -2
  383. data/src/examples/hello_trema/README.md +0 -2
  384. data/src/examples/hello_trema/hello-trema.rb +0 -30
  385. data/src/examples/hello_trema/hello_trema.c +0 -48
  386. data/src/examples/hello_trema/sample.conf +0 -1
  387. data/src/examples/learning_switch/README +0 -15
  388. data/src/examples/learning_switch/fdb.rb +0 -110
  389. data/src/examples/learning_switch/learning-switch.rb +0 -90
  390. data/src/examples/learning_switch/learning_switch.c +0 -217
  391. data/src/examples/learning_switch/learning_switch.conf +0 -18
  392. data/src/examples/list_switches/README +0 -19
  393. data/src/examples/list_switches/list-switches.rb +0 -43
  394. data/src/examples/list_switches/list_switches.c +0 -79
  395. data/src/examples/list_switches/list_switches.conf +0 -15
  396. data/src/examples/match_compare/match-compare.conf +0 -30
  397. data/src/examples/match_compare/match-compare.rb +0 -97
  398. data/src/examples/multi_learning_switch/README +0 -14
  399. data/src/examples/multi_learning_switch/multi-learning-switch.rb +0 -94
  400. data/src/examples/multi_learning_switch/multi_learning_switch.c +0 -294
  401. data/src/examples/multi_learning_switch/multi_learning_switch.conf +0 -17
  402. data/src/examples/openflow_message/README +0 -11
  403. data/src/examples/openflow_message/echo.c +0 -80
  404. data/src/examples/openflow_message/echo.rb +0 -56
  405. data/src/examples/openflow_message/example.rb +0 -60
  406. data/src/examples/openflow_message/features-request.rb +0 -96
  407. data/src/examples/openflow_message/features_request.c +0 -167
  408. data/src/examples/openflow_message/hello.c +0 -68
  409. data/src/examples/openflow_message/hello.rb +0 -43
  410. data/src/examples/openflow_message/set-config.rb +0 -57
  411. data/src/examples/openflow_message/set_config.c +0 -68
  412. data/src/examples/openflow_message/vendor-action.rb +0 -43
  413. data/src/examples/openflow_message/vendor-stats-request.rb +0 -66
  414. data/src/examples/openflow_message/vendor_action.c +0 -103
  415. data/src/examples/openflow_switch/echo_switch.c +0 -89
  416. data/src/examples/openflow_switch/hello_switch.c +0 -85
  417. data/src/examples/packet_in/README +0 -15
  418. data/src/examples/packet_in/packet-in.rb +0 -37
  419. data/src/examples/packet_in/packet_in.c +0 -53
  420. data/src/examples/packet_in/packet_in.conf +0 -15
  421. data/src/examples/packetin_filter_config/README +0 -12
  422. data/src/examples/packetin_filter_config/add_filter.c +0 -71
  423. data/src/examples/packetin_filter_config/delete_filter.c +0 -63
  424. data/src/examples/packetin_filter_config/delete_filter_strict.c +0 -73
  425. data/src/examples/packetin_filter_config/dump_filter.c +0 -63
  426. data/src/examples/packetin_filter_config/dump_filter_strict.c +0 -73
  427. data/src/examples/packetin_filter_config/packetin_filter_config.c +0 -132
  428. data/src/examples/packetin_filter_config/packetin_filter_config.conf +0 -7
  429. data/src/examples/packetin_filter_config/utils.c +0 -100
  430. data/src/examples/packetin_filter_config/utils.h +0 -40
  431. data/src/examples/patch_panel/network.conf +0 -14
  432. data/src/examples/patch_panel/patch-panel.conf +0 -1
  433. data/src/examples/patch_panel/patch-panel.rb +0 -59
  434. data/src/examples/repeater_hub/README +0 -8
  435. data/src/examples/repeater_hub/repeater-hub.rb +0 -41
  436. data/src/examples/repeater_hub/repeater-hub_spec.rb +0 -154
  437. data/src/examples/repeater_hub/repeater_hub.c +0 -81
  438. data/src/examples/repeater_hub/repeater_hub.conf +0 -28
  439. data/src/examples/simple_router/README +0 -18
  440. data/src/examples/simple_router/arp-table.rb +0 -81
  441. data/src/examples/simple_router/interface.rb +0 -90
  442. data/src/examples/simple_router/routing-table.rb +0 -60
  443. data/src/examples/simple_router/simple-router.rb +0 -191
  444. data/src/examples/simple_router/simple_router.conf +0 -24
  445. data/src/examples/simple_router/simple_router_netns.conf +0 -15
  446. data/src/examples/simple_router/simple_router_network.conf +0 -6
  447. data/src/examples/switch_event_config/.gitignore +0 -6
  448. data/src/examples/switch_event_config/add_forward_entry.c +0 -227
  449. data/src/examples/switch_event_config/delete_forward_entry.c +0 -226
  450. data/src/examples/switch_event_config/dump_forward_entries.c +0 -190
  451. data/src/examples/switch_event_config/network.conf +0 -2
  452. data/src/examples/switch_event_config/set_forward_entries.c +0 -210
  453. data/src/examples/switch_info/README +0 -13
  454. data/src/examples/switch_info/switch-info.rb +0 -44
  455. data/src/examples/switch_info/switch_info.c +0 -78
  456. data/src/examples/switch_info/switch_info.conf +0 -3
  457. data/src/examples/switch_monitor/switch-monitor.conf +0 -3
  458. data/src/examples/switch_monitor/switch-monitor.rb +0 -56
  459. data/src/examples/switch_monitor/switch_monitor.c +0 -152
  460. data/src/examples/traffic_monitor/counter.c +0 -72
  461. data/src/examples/traffic_monitor/counter.h +0 -46
  462. data/src/examples/traffic_monitor/counter.rb +0 -44
  463. data/src/examples/traffic_monitor/fdb.c +0 -74
  464. data/src/examples/traffic_monitor/fdb.h +0 -48
  465. data/src/examples/traffic_monitor/fdb.rb +0 -42
  466. data/src/examples/traffic_monitor/traffic-monitor.rb +0 -98
  467. data/src/examples/traffic_monitor/traffic_monitor.c +0 -161
  468. data/src/examples/traffic_monitor/traffic_monitor.conf +0 -16
  469. data/src/examples/transparent_firewall/README.md +0 -61
  470. data/src/examples/transparent_firewall/aggregated-delegated-afrinic.txt +0 -713
  471. data/src/examples/transparent_firewall/aggregated-delegated-apnic.txt +0 -3440
  472. data/src/examples/transparent_firewall/aggregated-delegated-arin.txt +0 -11342
  473. data/src/examples/transparent_firewall/aggregated-delegated-lacnic.txt +0 -1937
  474. data/src/examples/transparent_firewall/aggregated-delegated-ripencc.txt +0 -7329
  475. data/src/examples/transparent_firewall/block-rfc1918.rb +0 -86
  476. data/src/examples/transparent_firewall/pass-delegated.rb +0 -178
  477. data/src/examples/transparent_firewall/regen_aggregated.sh +0 -53
  478. data/src/examples/transparent_firewall/stats-to-cidrs.rb +0 -59
  479. data/src/lib/arp.h +0 -64
  480. data/src/lib/bool.h +0 -47
  481. data/src/lib/buffer.c +0 -304
  482. data/src/lib/buffer.h +0 -54
  483. data/src/lib/byteorder.c +0 -571
  484. data/src/lib/byteorder.h +0 -108
  485. data/src/lib/checks.h +0 -40
  486. data/src/lib/chibach.c +0 -392
  487. data/src/lib/chibach.h +0 -69
  488. data/src/lib/chibach_private.c +0 -168
  489. data/src/lib/chibach_private.h +0 -50
  490. data/src/lib/daemon.c +0 -429
  491. data/src/lib/daemon.h +0 -40
  492. data/src/lib/doubly_linked_list.c +0 -284
  493. data/src/lib/doubly_linked_list.h +0 -86
  494. data/src/lib/ether.c +0 -47
  495. data/src/lib/ether.h +0 -92
  496. data/src/lib/etherip.h +0 -44
  497. data/src/lib/event_forward_interface.c +0 -788
  498. data/src/lib/event_forward_interface.h +0 -138
  499. data/src/lib/event_handler.c +0 -419
  500. data/src/lib/event_handler.h +0 -57
  501. data/src/lib/external_callback.c +0 -126
  502. data/src/lib/external_callback.h +0 -46
  503. data/src/lib/hash_table.c +0 -415
  504. data/src/lib/hash_table.h +0 -136
  505. data/src/lib/icmp.h +0 -72
  506. data/src/lib/igmp.h +0 -48
  507. data/src/lib/ipv4.h +0 -64
  508. data/src/lib/ipv6.h +0 -46
  509. data/src/lib/linked_list.c +0 -244
  510. data/src/lib/linked_list.h +0 -84
  511. data/src/lib/log.c +0 -636
  512. data/src/lib/log.h +0 -77
  513. data/src/lib/management_interface.c +0 -359
  514. data/src/lib/management_interface.h +0 -40
  515. data/src/lib/management_service_interface.c +0 -102
  516. data/src/lib/management_service_interface.h +0 -134
  517. data/src/lib/match.h +0 -82
  518. data/src/lib/match_table.c +0 -606
  519. data/src/lib/match_table.h +0 -49
  520. data/src/lib/message_queue.c +0 -143
  521. data/src/lib/message_queue.h +0 -59
  522. data/src/lib/messenger.c +0 -1821
  523. data/src/lib/messenger.h +0 -145
  524. data/src/lib/openflow_application_interface.c +0 -1800
  525. data/src/lib/openflow_application_interface.h +0 -359
  526. data/src/lib/openflow_message.c +0 -4240
  527. data/src/lib/openflow_message.h +0 -291
  528. data/src/lib/openflow_service_interface.h +0 -58
  529. data/src/lib/openflow_switch_interface.c +0 -1378
  530. data/src/lib/openflow_switch_interface.h +0 -262
  531. data/src/lib/packet_info.c +0 -336
  532. data/src/lib/packet_info.h +0 -233
  533. data/src/lib/packet_parser.c +0 -522
  534. data/src/lib/packetin_filter_interface.c +0 -292
  535. data/src/lib/packetin_filter_interface.h +0 -125
  536. data/src/lib/persistent_storage.c +0 -478
  537. data/src/lib/persistent_storage.h +0 -44
  538. data/src/lib/secure_channel.c +0 -496
  539. data/src/lib/secure_channel.h +0 -43
  540. data/src/lib/stat.c +0 -248
  541. data/src/lib/stat.h +0 -51
  542. data/src/lib/tcp.h +0 -62
  543. data/src/lib/timer.c +0 -349
  544. data/src/lib/timer.h +0 -51
  545. data/src/lib/trema.c +0 -776
  546. data/src/lib/trema.h +0 -80
  547. data/src/lib/trema.hpp +0 -49
  548. data/src/lib/trema_private.c +0 -175
  549. data/src/lib/trema_private.h +0 -64
  550. data/src/lib/trema_wrapper.c +0 -59
  551. data/src/lib/trema_wrapper.h +0 -66
  552. data/src/lib/udp.h +0 -41
  553. data/src/lib/utility.c +0 -625
  554. data/src/lib/utility.h +0 -84
  555. data/src/lib/wrapper.c +0 -121
  556. data/src/lib/wrapper.h +0 -76
  557. data/src/management/application.c +0 -222
  558. data/src/management/echo.c +0 -183
  559. data/src/management/set_logging_level.c +0 -151
  560. data/src/management/show_stats.c +0 -148
  561. data/src/management/trema_manager +0 -184
  562. data/src/packetin_filter/README +0 -17
  563. data/src/packetin_filter/packetin_filter.c +0 -575
  564. data/src/switch_manager/README +0 -20
  565. data/src/switch_manager/cookie_table.c +0 -290
  566. data/src/switch_manager/cookie_table.h +0 -70
  567. data/src/switch_manager/dpid_table.c +0 -108
  568. data/src/switch_manager/dpid_table.h +0 -43
  569. data/src/switch_manager/event_forward_entry_manipulation.c +0 -120
  570. data/src/switch_manager/event_forward_entry_manipulation.h +0 -31
  571. data/src/switch_manager/ofpmsg_recv.c +0 -497
  572. data/src/switch_manager/ofpmsg_recv.h +0 -39
  573. data/src/switch_manager/ofpmsg_send.c +0 -274
  574. data/src/switch_manager/ofpmsg_send.h +0 -51
  575. data/src/switch_manager/secure_channel_listener.c +0 -296
  576. data/src/switch_manager/secure_channel_listener.h +0 -40
  577. data/src/switch_manager/secure_channel_receiver.c +0 -129
  578. data/src/switch_manager/secure_channel_receiver.h +0 -40
  579. data/src/switch_manager/secure_channel_sender.c +0 -131
  580. data/src/switch_manager/secure_channel_sender.h +0 -41
  581. data/src/switch_manager/service_interface.c +0 -180
  582. data/src/switch_manager/service_interface.h +0 -44
  583. data/src/switch_manager/switch.c +0 -988
  584. data/src/switch_manager/switch.h +0 -50
  585. data/src/switch_manager/switch_manager.c +0 -643
  586. data/src/switch_manager/switch_manager.h +0 -65
  587. data/src/switch_manager/switch_option.c +0 -30
  588. data/src/switch_manager/switch_option.h +0 -41
  589. data/src/switch_manager/switchinfo.h +0 -81
  590. data/src/switch_manager/xid_table.c +0 -182
  591. data/src/switch_manager/xid_table.h +0 -53
  592. data/src/tremashark/README +0 -79
  593. data/src/tremashark/packet_capture.c +0 -358
  594. data/src/tremashark/pcap_private.h +0 -45
  595. data/src/tremashark/pcap_queue.c +0 -195
  596. data/src/tremashark/pcap_queue.h +0 -56
  597. data/src/tremashark/plugin/.gitignore +0 -6
  598. data/src/tremashark/plugin/packet-trema/.gitignore +0 -5
  599. data/src/tremashark/plugin/packet-trema/Makefile +0 -77
  600. data/src/tremashark/plugin/packet-trema/Makefile.am +0 -110
  601. data/src/tremashark/plugin/packet-trema/Makefile.common +0 -29
  602. data/src/tremashark/plugin/packet-trema/moduleinfo.h +0 -39
  603. data/src/tremashark/plugin/packet-trema/packet-trema.c +0 -1671
  604. data/src/tremashark/plugin/packet-trema/plugin.c +0 -31
  605. data/src/tremashark/plugin/user_dlts +0 -2
  606. data/src/tremashark/queue.c +0 -167
  607. data/src/tremashark/queue.h +0 -58
  608. data/src/tremashark/stdin_relay.c +0 -257
  609. data/src/tremashark/syslog_relay.c +0 -247
  610. data/src/tremashark/tremashark.c +0 -554
  611. data/trema +0 -11
  612. data/trema-config +0 -11
  613. data/unittests/buffer_stubs.c +0 -72
  614. data/unittests/cmockery_trema.c +0 -121
  615. data/unittests/cmockery_trema.h +0 -95
  616. data/unittests/lib/buffer_test.c +0 -368
  617. data/unittests/lib/byteorder_test.c +0 -1798
  618. data/unittests/lib/daemon_test.c +0 -804
  619. data/unittests/lib/doubly_linked_list_test.c +0 -348
  620. data/unittests/lib/ether_test.c +0 -125
  621. data/unittests/lib/event_forward_interface_test.c +0 -1676
  622. data/unittests/lib/external_callback_test.c +0 -282
  623. data/unittests/lib/hash_table_test.c +0 -278
  624. data/unittests/lib/linked_list_test.c +0 -434
  625. data/unittests/lib/log_test.c +0 -672
  626. data/unittests/lib/management_interface_test.c +0 -238
  627. data/unittests/lib/management_service_interface_test.c +0 -317
  628. data/unittests/lib/match_table_test.c +0 -1507
  629. data/unittests/lib/message_queue_test.c +0 -381
  630. data/unittests/lib/messenger_test.c +0 -623
  631. data/unittests/lib/openflow_application_interface_test.c +0 -3713
  632. data/unittests/lib/openflow_message_test.c +0 -8047
  633. data/unittests/lib/packet_info_test.c +0 -558
  634. data/unittests/lib/packet_parser_test.c +0 -784
  635. data/unittests/lib/packetin_filter_interface_test.c +0 -721
  636. data/unittests/lib/persistent_storage_test.c +0 -800
  637. data/unittests/lib/stat_test.c +0 -433
  638. data/unittests/lib/test_packets/arp_rep.cap +0 -0
  639. data/unittests/lib/test_packets/arp_req.cap +0 -0
  640. data/unittests/lib/test_packets/icmp6_echo_rep.cap +0 -0
  641. data/unittests/lib/test_packets/icmp6_echo_req.cap +0 -0
  642. data/unittests/lib/test_packets/icmp_echo_rep.cap +0 -0
  643. data/unittests/lib/test_packets/icmp_echo_req.cap +0 -0
  644. data/unittests/lib/test_packets/igmp_query_v2.cap +0 -0
  645. data/unittests/lib/test_packets/ipx.cap +0 -0
  646. data/unittests/lib/test_packets/lldp.cap +0 -0
  647. data/unittests/lib/test_packets/lldp_over_ip.cap +0 -0
  648. data/unittests/lib/test_packets/rarp_req.cap +0 -0
  649. data/unittests/lib/test_packets/tcp.cap +0 -0
  650. data/unittests/lib/test_packets/tcp_syn.cap +0 -0
  651. data/unittests/lib/test_packets/udp.cap +0 -0
  652. data/unittests/lib/test_packets/udp_frag_head.cap +0 -0
  653. data/unittests/lib/test_packets/udp_frag_next.cap +0 -0
  654. data/unittests/lib/test_packets/vtag_icmp_echo_rep.cap +0 -0
  655. data/unittests/lib/test_packets/vtag_icmp_echo_req.cap +0 -0
  656. data/unittests/lib/timer_test.c +0 -246
  657. data/unittests/lib/trema_private_test.c +0 -321
  658. data/unittests/lib/trema_test.c +0 -1030
  659. data/unittests/lib/utility_test.c +0 -711
  660. data/unittests/lib/wrapper_test.c +0 -228
  661. data/unittests/packetin_filter/packetin_filter_test.c +0 -476
  662. data/unittests/switch_manager/switch_manager_test.c +0 -1183
  663. data/unittests/wrapper_stubs.c +0 -37
  664. data/vendor/.gitignore +0 -6
  665. data/vendor/README.md +0 -29
  666. data/vendor/cmockery-20110428.tar.gz +0 -0
  667. data/vendor/oflops-0.03.trema1.tar.gz +0 -0
  668. data/vendor/oflops_no_snmp+1.0.0.diff +0 -340
  669. data/vendor/openflow-1.0.0.tar.gz +0 -0
  670. data/vendor/openflow.git.tar.gz +0 -0
  671. data/vendor/openvswitch-1.2.2.trema1.tar.gz +0 -0
  672. data/vendor/openvswitch-1.2.2_librt-check.diff +0 -21
  673. data/vendor/packet-openflow.diff +0 -13
  674. data/vendor/ruby-ifconfig-1.2/COPYING +0 -340
  675. data/vendor/ruby-ifconfig-1.2/Changelog +0 -16
  676. data/vendor/ruby-ifconfig-1.2/INSTALL +0 -239
  677. data/vendor/ruby-ifconfig-1.2/README +0 -38
  678. data/vendor/ruby-ifconfig-1.2/Rakefile +0 -14
  679. data/vendor/ruby-ifconfig-1.2/TODO +0 -8
  680. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/darwin.txt +0 -17
  681. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/dragonflybsd.txt +0 -10
  682. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/dragonflybsd_netstat.txt +0 -14
  683. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/freebsd.txt +0 -17
  684. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/freebsd_netstat.txt +0 -24
  685. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/linux.txt +0 -60
  686. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/linux_ethernet.txt +0 -20
  687. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/netbsd.txt +0 -10
  688. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/openbsd.txt +0 -36
  689. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/sunos.txt +0 -10
  690. data/vendor/ruby-ifconfig-1.2/lib/ifconfig.rb +0 -71
  691. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/bsd/ifconfig.rb +0 -72
  692. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/bsd/interface_types.rb +0 -69
  693. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/bsd/network_types.rb +0 -3
  694. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/common/ifconfig.rb +0 -84
  695. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/common/interface_types.rb +0 -130
  696. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/common/network_types.rb +0 -49
  697. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/linux/ifconfig.rb +0 -43
  698. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/linux/interface_types.rb +0 -112
  699. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/linux/network_types.rb +0 -55
  700. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/sunos/ifconfig.rb +0 -38
  701. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/sunos/interface_types.rb +0 -77
  702. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/sunos/network_types.rb +0 -4
  703. data/vendor/ruby-ifconfig-1.2/setup.rb +0 -1306
  704. data/vendor/ruby-ifconfig-1.2/test/test_bsd.rb +0 -35
  705. data/vendor/ruby-ifconfig-1.2/test/test_darwin.rb +0 -33
  706. data/vendor/ruby-ifconfig-1.2/test/test_dragonflybsd.rb +0 -35
  707. data/vendor/ruby-ifconfig-1.2/test/test_helper.rb +0 -4
  708. data/vendor/ruby-ifconfig-1.2/test/test_linux.rb +0 -31
  709. data/vendor/ruby-ifconfig-1.2/test/test_netbsd.rb +0 -33
  710. data/vendor/ruby-ifconfig-1.2/test/test_openbsd.rb +0 -33
  711. data/vendor/ruby-ifconfig-1.2/test/test_sunos.rb +0 -35
  712. data/vendor/ruby-ifconfig-1.2/test/unit/tc_darwin.rb +0 -40
  713. data/vendor/ruby-ifconfig-1.2/test/unit/tc_dragonflybsd.rb +0 -39
  714. data/vendor/ruby-ifconfig-1.2/test/unit/tc_freebsd.rb +0 -40
  715. data/vendor/ruby-ifconfig-1.2/test/unit/tc_linux.rb +0 -49
  716. data/vendor/ruby-ifconfig-1.2/test/unit/tc_netbsd.rb +0 -39
  717. data/vendor/ruby-ifconfig-1.2/test/unit/tc_openbsd.rb +0 -39
  718. data/vendor/ruby-ifconfig-1.2/test/unit/tc_sunos.rb +0 -44
@@ -1,359 +0,0 @@
1
- /*
2
- * An OpenFlow application interface library.
3
- *
4
- * Copyright (C) 2008-2013 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
- #ifndef OPENFLOW_APPLICATION_INTERFACE_H
22
- #define OPENFLOW_APPLICATION_INTERFACE_H
23
-
24
-
25
- #include <arpa/inet.h>
26
- #include "buffer.h"
27
- #include "linked_list.h"
28
- #include "openflow.h"
29
- #include "openflow_service_interface.h"
30
-
31
-
32
- /********************************************************************************
33
- * Functions for initializing/finalizing the OpenFlow application interface.
34
- ********************************************************************************/
35
-
36
- bool init_openflow_application_interface( const char *service_name );
37
- bool finalize_openflow_application_interface( void );
38
- bool openflow_application_interface_is_initialized( void );
39
-
40
-
41
- /********************************************************************************
42
- * Event handler definitions.
43
- ********************************************************************************/
44
-
45
- typedef struct {
46
- uint64_t datapath_id;
47
- void *user_data;
48
- } switch_ready;
49
-
50
- typedef void ( simple_switch_ready_handler )( switch_ready event );
51
-
52
- typedef void ( switch_ready_handler )(
53
- uint64_t datapath_id,
54
- void *user_data
55
- );
56
-
57
-
58
- typedef void ( *switch_disconnected_handler )(
59
- uint64_t datapath_id,
60
- void *user_data
61
- );
62
-
63
-
64
- typedef void ( *error_handler )(
65
- uint64_t datapath_id,
66
- uint32_t transaction_id,
67
- uint16_t type,
68
- uint16_t code,
69
- const buffer *data,
70
- void *user_data
71
- );
72
-
73
-
74
- typedef void ( *echo_reply_handler )(
75
- uint64_t datapath_id,
76
- uint32_t transaction_id,
77
- const buffer *data,
78
- void *user_data
79
- );
80
-
81
-
82
- typedef void ( *vendor_handler )(
83
- uint64_t datapath_id,
84
- uint32_t transaction_id,
85
- uint32_t vendor,
86
- const buffer *data,
87
- void *user_data
88
- );
89
-
90
-
91
- typedef void ( *features_reply_handler )(
92
- uint64_t datapath_id,
93
- uint32_t transaction_id,
94
- uint32_t n_buffers,
95
- uint8_t n_tables,
96
- uint32_t capabilities,
97
- uint32_t actions,
98
- const list_element *phy_ports,
99
- void *user_data
100
- );
101
-
102
-
103
- typedef void ( *get_config_reply_handler )(
104
- uint64_t datapath_id,
105
- uint32_t transaction_id,
106
- uint16_t flags,
107
- uint16_t miss_send_len,
108
- void *user_data
109
- );
110
-
111
-
112
- typedef struct {
113
- uint64_t datapath_id;
114
- uint32_t transaction_id;
115
- uint32_t buffer_id;
116
- uint16_t total_len;
117
- uint16_t in_port;
118
- uint8_t reason;
119
- const buffer *data;
120
- void *user_data;
121
- } packet_in;
122
-
123
- typedef void ( simple_packet_in_handler )( uint64_t datapath_id, packet_in message );
124
- typedef void ( packet_in_handler )(
125
- uint64_t datapath_id,
126
- uint32_t transaction_id,
127
- uint32_t buffer_id,
128
- uint16_t total_len,
129
- uint16_t in_port,
130
- uint8_t reason,
131
- const buffer *data,
132
- void *user_data
133
- );
134
-
135
-
136
- typedef struct {
137
- uint64_t datapath_id;
138
- uint32_t transaction_id;
139
- struct ofp_match match;
140
- uint64_t cookie;
141
- uint16_t priority;
142
- uint8_t reason;
143
- uint32_t duration_sec;
144
- uint32_t duration_nsec;
145
- uint16_t idle_timeout;
146
- uint64_t packet_count;
147
- uint64_t byte_count;
148
- void *user_data;
149
- } flow_removed;
150
-
151
- typedef void ( simple_flow_removed_handler )( uint64_t datapath_id, flow_removed message );
152
- typedef void ( flow_removed_handler )(
153
- uint64_t datapath_id,
154
- uint32_t transaction_id,
155
- struct ofp_match match,
156
- uint64_t cookie,
157
- uint16_t priority,
158
- uint8_t reason,
159
- uint32_t duration_sec,
160
- uint32_t duration_nsec,
161
- uint16_t idle_timeout,
162
- uint64_t packet_count,
163
- uint64_t byte_count,
164
- void *user_data
165
- );
166
-
167
-
168
- typedef void ( *port_status_handler )(
169
- uint64_t datapath_id,
170
- uint32_t transaction_id,
171
- uint8_t reason,
172
- struct ofp_phy_port phy_port,
173
- void *user_data
174
- );
175
-
176
-
177
- typedef void ( *stats_reply_handler )(
178
- uint64_t datapath_id,
179
- uint32_t transaction_id,
180
- uint16_t type,
181
- uint16_t flags,
182
- const buffer *data,
183
- void *user_data
184
- );
185
-
186
-
187
- typedef void ( *barrier_reply_handler )(
188
- uint64_t datapath_id,
189
- uint32_t transaction_id,
190
- void *user_data
191
- );
192
-
193
-
194
- typedef void ( *queue_get_config_reply_handler )(
195
- uint64_t datapath_id,
196
- uint32_t transaction_id,
197
- uint16_t port,
198
- const list_element *queues,
199
- void *user_data
200
- );
201
-
202
-
203
- typedef void ( *list_switches_reply_handler )(
204
- const list_element *switches,
205
- void *user_data
206
- );
207
-
208
-
209
- typedef struct openflow_event_handlers {
210
- bool simple_switch_ready_callback;
211
- void *switch_ready_callback;
212
- void *switch_ready_user_data;
213
-
214
- switch_disconnected_handler switch_disconnected_callback;
215
- void *switch_disconnected_user_data;
216
-
217
- error_handler error_callback;
218
- void *error_user_data;
219
-
220
- echo_reply_handler echo_reply_callback;
221
- void *echo_reply_user_data;
222
-
223
- vendor_handler vendor_callback;
224
- void *vendor_user_data;
225
-
226
- features_reply_handler features_reply_callback;
227
- void *features_reply_user_data;
228
-
229
- get_config_reply_handler get_config_reply_callback;
230
- void *get_config_reply_user_data;
231
-
232
- bool simple_packet_in_callback;
233
- void *packet_in_callback;
234
- void *packet_in_user_data;
235
-
236
- bool simple_flow_removed_callback;
237
- void *flow_removed_callback;
238
- void *flow_removed_user_data;
239
-
240
- port_status_handler port_status_callback;
241
- void *port_status_user_data;
242
-
243
- stats_reply_handler stats_reply_callback;
244
- void *stats_reply_user_data;
245
-
246
- barrier_reply_handler barrier_reply_callback;
247
- void *barrier_reply_user_data;
248
-
249
- queue_get_config_reply_handler queue_get_config_reply_callback;
250
- void *queue_get_config_reply_user_data;
251
-
252
- list_switches_reply_handler list_switches_reply_callback;
253
- } openflow_event_handlers_t;
254
-
255
-
256
- /********************************************************************************
257
- * Functions for setting callback functions for OpenFlow related events.
258
- ********************************************************************************/
259
-
260
- bool set_openflow_event_handlers( const openflow_event_handlers_t handlers );
261
-
262
- #define set_switch_ready_handler( callback, user_data ) \
263
- { \
264
- if ( __builtin_types_compatible_p( typeof( callback ), simple_switch_ready_handler ) ) { \
265
- _set_switch_ready_handler( true, ( void * ) callback, user_data ); \
266
- } \
267
- else if ( __builtin_types_compatible_p( typeof( callback ), switch_ready_handler ) ) { \
268
- _set_switch_ready_handler( false, ( void * ) callback, user_data ); \
269
- } \
270
- else { \
271
- _set_switch_ready_handler( false, NULL, NULL ); \
272
- } \
273
- }
274
- bool _set_switch_ready_handler( bool simple_callback, void *callback, void *user_data );
275
-
276
-
277
- bool set_switch_disconnected_handler( switch_disconnected_handler callback, void *user_data );
278
- bool set_error_handler( error_handler callback, void *user_data );
279
- bool set_echo_reply_handler( echo_reply_handler callback, void *user_data );
280
- bool set_vendor_handler( vendor_handler callback, void *user_data );
281
- bool set_features_reply_handler( features_reply_handler callback, void *user_data );
282
- bool set_get_config_reply_handler( get_config_reply_handler callback, void *user_data );
283
-
284
-
285
- #define set_packet_in_handler( callback, user_data ) \
286
- { \
287
- if ( __builtin_types_compatible_p( typeof( callback ), simple_packet_in_handler ) ) { \
288
- _set_packet_in_handler( true, ( void * ) callback, user_data ); \
289
- } \
290
- else if ( __builtin_types_compatible_p( typeof( callback ), packet_in_handler ) ) { \
291
- _set_packet_in_handler( false, ( void * ) callback, user_data ); \
292
- } \
293
- else { \
294
- _set_packet_in_handler( false, NULL, NULL ); \
295
- } \
296
- }
297
- bool _set_packet_in_handler( bool simple_callback, void *callback, void *user_data );
298
-
299
-
300
- #define set_flow_removed_handler( callback, user_data ) \
301
- { \
302
- if ( __builtin_types_compatible_p( typeof( callback ), simple_flow_removed_handler ) ) { \
303
- _set_flow_removed_handler( true, ( void * ) callback, user_data ); \
304
- } \
305
- else if ( __builtin_types_compatible_p( typeof( callback ), flow_removed_handler ) ) { \
306
- _set_flow_removed_handler( false, ( void * ) callback, user_data ); \
307
- } \
308
- else { \
309
- _set_flow_removed_handler( false, NULL, NULL ); \
310
- } \
311
- }
312
- bool _set_flow_removed_handler( bool simple_callback, void *callback, void *user_data );
313
-
314
-
315
- bool set_port_status_handler( port_status_handler callback, void *user_data );
316
- bool set_stats_reply_handler( stats_reply_handler callback, void *user_data );
317
- bool set_barrier_reply_handler( barrier_reply_handler callback, void *user_data );
318
- bool set_queue_get_config_reply_handler( queue_get_config_reply_handler callback, void *user_data );
319
-
320
- bool set_list_switches_reply_handler( list_switches_reply_handler callback );
321
-
322
-
323
- /********************************************************************************
324
- * Function for sending an OpenFlow message to an OpenFlow switch.
325
- ********************************************************************************/
326
-
327
- bool send_openflow_message( const uint64_t datapath_id, buffer *message );
328
-
329
-
330
- /********************************************************************************
331
- * Function for retrieving the list of switches from Switch Manager.
332
- ********************************************************************************/
333
-
334
- bool send_list_switches_request( void *user_data );
335
-
336
-
337
- /********************************************************************************
338
- * Function for deleting OpenFlow messages in a send queue
339
- ********************************************************************************/
340
-
341
- bool delete_openflow_messages( uint64_t datapath_id );
342
-
343
-
344
- /********************************************************************************
345
- * Function for disconnecting a switch
346
- ********************************************************************************/
347
-
348
- bool disconnect_switch( uint64_t datapath_id );
349
-
350
-
351
- #endif // OPENFLOW_APPLICATION_INTERFACE_H
352
-
353
-
354
- /*
355
- * Local variables:
356
- * c-basic-offset: 2
357
- * indent-tabs-mode: nil
358
- * End:
359
- */
@@ -1,4240 +0,0 @@
1
- /*
2
- * Copyright (C) 2008-2013 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
- #include <arpa/inet.h>
20
- #include <assert.h>
21
- #include <inttypes.h>
22
- #include <pthread.h>
23
- #include <string.h>
24
- #include <sys/socket.h>
25
- #include <sys/types.h>
26
- #include <syslog.h>
27
- #include <unistd.h>
28
- #include "openflow_message.h"
29
- #include "packet_info.h"
30
- #include "wrapper.h"
31
- #include "log.h"
32
-
33
-
34
- #ifdef UNIT_TESTING
35
-
36
- // Allow static functions to be called from unit tests.
37
- #define static
38
-
39
- /* Redirect getpid to a function in the test application so it's
40
- * possible to test if pid value is correctly used. */
41
- #ifdef getpid
42
- #undef getpid
43
- #endif // getpid
44
- #define getpid mock_getpid
45
- extern pid_t mock_getpid( void );
46
-
47
- /* Redirect debug to a function in the test application so it's
48
- * possible to test if debug messages are generated expectedly. */
49
- #ifdef debug
50
- #undef debug
51
- #endif // debug
52
- #define debug mock_debug
53
- extern void mock_debug( const char *format, ... );
54
-
55
- #endif // UNIT_TESTING
56
-
57
-
58
- #define VLAN_VID_MASK 0x0fff // 12 bits
59
- #define VLAN_PCP_MASK 0x07 // 3 bits
60
- #define NW_TOS_MASK 0xfc // upper 6 bits
61
- #define ARP_OP_MASK 0x00ff // 8 bits
62
- #define ICMP_TYPE_MASK 0x00ff // 8 bits
63
- #define ICMP_CODE_MASK 0x00ff // 8 bits
64
-
65
- #define PORT_CONFIG ( OFPPC_PORT_DOWN | OFPPC_NO_STP | OFPPC_NO_RECV \
66
- | OFPPC_NO_RECV_STP | OFPPC_NO_FLOOD | OFPPC_NO_FWD \
67
- | OFPPC_NO_PACKET_IN )
68
- #define PORT_STATE ( OFPPS_LINK_DOWN | OFPPS_STP_LISTEN | OFPPS_STP_LEARN \
69
- | OFPPS_STP_FORWARD | OFPPS_STP_BLOCK | OFPPS_STP_MASK )
70
- #define PORT_FEATURES ( OFPPF_10MB_HD | OFPPF_10MB_FD | OFPPF_100MB_HD \
71
- | OFPPF_100MB_FD | OFPPF_1GB_HD | OFPPF_1GB_FD \
72
- | OFPPF_10GB_FD | OFPPF_COPPER | OFPPF_FIBER \
73
- | OFPPF_AUTONEG | OFPPF_PAUSE | OFPPF_PAUSE_ASYM )
74
- #define FLOW_MOD_FLAGS ( OFPFF_SEND_FLOW_REM | OFPFF_CHECK_OVERLAP | OFPFF_EMERG )
75
-
76
-
77
- static uint32_t transaction_id = 0;
78
- static pthread_mutex_t transaction_id_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
79
-
80
- static uint64_t cookie = 0;
81
- static pthread_mutex_t cookie_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
82
-
83
-
84
- bool
85
- init_openflow_message( void ) {
86
- pid_t pid;
87
-
88
- pid = getpid();
89
-
90
- pthread_mutex_lock( &transaction_id_mutex );
91
- transaction_id = ( uint32_t ) pid << 16;
92
- pthread_mutex_unlock( &transaction_id_mutex );
93
-
94
- pthread_mutex_lock( &cookie_mutex );
95
- cookie = ( uint64_t ) pid << 48;
96
- pthread_mutex_unlock( &cookie_mutex );
97
-
98
- debug( "transaction_id and cookie are initialized ( transaction_id = %#x, cookie = %#" PRIx64 " ).",
99
- transaction_id, cookie );
100
-
101
- return true;
102
- }
103
-
104
-
105
- static buffer *
106
- create_header( const uint32_t transaction_id, const uint8_t type, const uint16_t length ) {
107
- debug( "Creating an OpenFlow header ( version = %#x, type = %#x, length = %u, xid = %#x ).",
108
- OFP_VERSION, type, length, transaction_id );
109
-
110
- assert( length >= sizeof( struct ofp_header ) );
111
-
112
- buffer *buffer = alloc_buffer();
113
- assert( buffer != NULL );
114
-
115
- struct ofp_header *header = append_back_buffer( buffer, length );
116
- assert( header != NULL );
117
- memset( header, 0, length );
118
-
119
- header->version = OFP_VERSION;
120
- header->type = type;
121
- header->length = htons( length );
122
- header->xid = htonl( transaction_id );
123
-
124
- return buffer;
125
- }
126
-
127
-
128
- buffer *
129
- create_error( const uint32_t transaction_id, const uint16_t type,
130
- const uint16_t code, const buffer *data ) {
131
- uint16_t length;
132
- uint16_t data_len = 0;
133
- buffer *buffer;
134
- struct ofp_error_msg *error_msg;
135
-
136
- if ( ( data != NULL ) && ( data->length > 0 ) ) {
137
- data_len = ( uint16_t ) data->length;
138
- }
139
-
140
- debug( "Creating an error ( xid = %#x, type = %#x, code = %#x, data length = %u ).",
141
- transaction_id, type, code, data_len );
142
-
143
- length = ( uint16_t ) ( sizeof( struct ofp_error_msg ) + data_len );
144
- buffer = create_header( transaction_id, OFPT_ERROR, length );
145
- assert( buffer != NULL );
146
-
147
- error_msg = ( struct ofp_error_msg * ) buffer->data;
148
- error_msg->type = htons( type );
149
- error_msg->code = htons( code );
150
-
151
- if ( data_len > 0 ) {
152
- memcpy( error_msg->data, data->data, data->length );
153
- }
154
-
155
- return buffer;
156
- }
157
-
158
-
159
- buffer *
160
- create_hello( const uint32_t transaction_id ) {
161
- debug( "Creating a hello ( xid = %#x ).", transaction_id );
162
-
163
- return create_header( transaction_id, OFPT_HELLO, sizeof( struct ofp_header ) );
164
- }
165
-
166
-
167
- buffer *
168
- create_echo_request( const uint32_t transaction_id, const buffer *body ) {
169
- uint16_t data_length = 0;
170
-
171
- if ( ( body != NULL ) && ( body->length > 0 ) ) {
172
- data_length = ( uint16_t ) body->length;
173
- }
174
-
175
- debug( "Creating an echo request ( xid = %#x, data length = %u ).", transaction_id, data_length );
176
-
177
- buffer *echo_request = create_header( transaction_id, OFPT_ECHO_REQUEST, ( uint16_t ) ( sizeof( struct ofp_header ) + data_length ) );
178
- assert( echo_request != NULL );
179
-
180
- if ( data_length > 0 ) {
181
- memcpy( ( char * ) echo_request->data + sizeof( struct ofp_header ), body->data, data_length );
182
- }
183
-
184
- return echo_request;
185
- }
186
-
187
-
188
- buffer *
189
- create_echo_reply( const uint32_t transaction_id, const buffer *body ) {
190
- uint16_t data_length = 0;
191
-
192
- if ( ( body != NULL ) && ( body->length > 0 ) ) {
193
- data_length = ( uint16_t ) body->length;
194
- }
195
-
196
- debug( "Creating an echo reply ( xid = %#x, data length = %u ).", transaction_id, data_length );
197
-
198
- buffer *echo_reply = create_header( transaction_id, OFPT_ECHO_REPLY, ( uint16_t ) ( sizeof( struct ofp_header ) + data_length ) );
199
- assert( echo_reply != NULL );
200
-
201
- if ( data_length > 0 ) {
202
- memcpy( ( char * ) echo_reply->data + sizeof( struct ofp_header ), body->data, data_length );
203
- }
204
-
205
- return echo_reply;
206
- }
207
-
208
-
209
- buffer *
210
- create_vendor( const uint32_t transaction_id, const uint32_t vendor, const buffer *data ) {
211
- void *d;
212
- uint16_t length;
213
- uint16_t data_length = 0;
214
- buffer *buffer;
215
- struct ofp_vendor_header *vendor_header;
216
-
217
- if ( ( data != NULL ) && ( data->length > 0 ) ) {
218
- data_length = ( uint16_t ) data->length;
219
- }
220
-
221
- debug( "Creating a vendor ( xid = %#x, vendor = %#x, data length = %u ).",
222
- transaction_id, vendor, data_length );
223
-
224
- length = ( uint16_t ) ( sizeof( struct ofp_vendor_header ) + data_length );
225
- buffer = create_header( transaction_id, OFPT_VENDOR, length );
226
- assert( buffer != NULL );
227
-
228
- vendor_header = ( struct ofp_vendor_header * ) buffer->data;
229
- vendor_header->vendor = htonl( vendor );
230
-
231
- if ( data_length > 0 ) {
232
- d = ( void * ) ( ( char * ) buffer->data + sizeof( struct ofp_vendor_header ) );
233
- memcpy( d, data->data, data_length );
234
- }
235
-
236
- return buffer;
237
- }
238
-
239
-
240
- buffer *
241
- create_features_request( const uint32_t transaction_id ) {
242
- debug( "Creating a features request ( xid = %#x ).", transaction_id );
243
-
244
- return create_header( transaction_id, OFPT_FEATURES_REQUEST, sizeof( struct ofp_header ) );
245
- }
246
-
247
-
248
- buffer *
249
- create_features_reply( const uint32_t transaction_id, const uint64_t datapath_id,
250
- const uint32_t n_buffers, const uint8_t n_tables,
251
- const uint32_t capabilities, const uint32_t actions,
252
- const list_element *ports ) {
253
- char port_str[ 1024 ];
254
- int count = 0;
255
- uint16_t n_ports = 0;
256
- buffer *buffer;
257
- struct ofp_switch_features *switch_features;
258
- struct ofp_phy_port *phy_port;
259
- struct ofp_phy_port pn;
260
- list_element *p = NULL, *port;
261
-
262
- debug( "Creating a features reply "
263
- "( xid = %#x, datapath_id = %#" PRIx64 ", n_buffers = %u, n_tables = %u, capabilities = %#x, actions = %#x ).",
264
- transaction_id, datapath_id, n_buffers, n_tables, capabilities, actions );
265
-
266
- if ( ports != NULL ) {
267
- p = ( list_element * ) xmalloc( sizeof( list_element ) );
268
- memcpy( p, ports, sizeof( list_element ) );
269
-
270
- port = p;
271
- while ( port != NULL ) {
272
- port = port->next;
273
- n_ports++;
274
- }
275
- }
276
-
277
- debug( "# of ports = %u.", n_ports );
278
-
279
- buffer = create_header( transaction_id, OFPT_FEATURES_REPLY,
280
- ( uint16_t ) ( offsetof( struct ofp_switch_features, ports )
281
- + sizeof( struct ofp_phy_port ) * n_ports ) );
282
- assert( buffer != NULL );
283
-
284
- switch_features = ( struct ofp_switch_features * ) buffer->data;
285
- switch_features->datapath_id = htonll( datapath_id );
286
- switch_features->n_buffers = htonl( n_buffers );
287
- switch_features->n_tables = n_tables;
288
- memset( switch_features->pad, 0, sizeof( switch_features->pad ) );
289
- switch_features->capabilities = htonl( capabilities );
290
- switch_features->actions = htonl( actions );
291
-
292
- if ( n_ports ) {
293
- phy_port = ( struct ofp_phy_port * ) ( ( char * ) buffer->data
294
- + offsetof( struct ofp_switch_features, ports ) );
295
- port = p;
296
- while ( port != NULL ) {
297
- phy_port_to_string( port->data, port_str, sizeof( port_str ) );
298
- debug( "[%u] %s", count++, port_str );
299
- hton_phy_port( &pn, ( struct ofp_phy_port * ) port->data );
300
- memcpy( phy_port, &pn, sizeof( struct ofp_phy_port ) );
301
- port = port->next;
302
- phy_port++;
303
- }
304
-
305
- xfree( p );
306
- }
307
-
308
- return buffer;
309
- }
310
-
311
-
312
- buffer *
313
- create_get_config_request( const uint32_t transaction_id ) {
314
- debug( "Creating a get config request ( xid = %#x ).", transaction_id );
315
-
316
- return create_header( transaction_id, OFPT_GET_CONFIG_REQUEST, sizeof( struct ofp_header ) );
317
- }
318
-
319
-
320
- buffer *
321
- create_get_config_reply( const uint32_t transaction_id, const uint16_t flags,
322
- const uint16_t miss_send_len ) {
323
- buffer *buffer;
324
- struct ofp_switch_config *switch_config;
325
-
326
- debug( "Creating a get config reply ( xid = %#x, flags = %#x, miss_send_len = %u ).",
327
- transaction_id, flags, miss_send_len );
328
-
329
- buffer = create_header( transaction_id, OFPT_GET_CONFIG_REPLY, sizeof( struct ofp_switch_config ) );
330
- assert( buffer != NULL );
331
-
332
- switch_config = ( struct ofp_switch_config * ) buffer->data;
333
- switch_config->flags = htons( flags );
334
- switch_config->miss_send_len = htons( miss_send_len );
335
-
336
- return buffer;
337
- }
338
-
339
-
340
- buffer *
341
- create_set_config( const uint32_t transaction_id, const uint16_t flags, uint16_t miss_send_len ) {
342
- debug( "Creating a set config ( xid = %#x, flags = %#x, miss_send_len = %u ).",
343
- transaction_id, flags, miss_send_len );
344
-
345
- buffer *set_config = create_header( transaction_id, OFPT_SET_CONFIG, sizeof( struct ofp_switch_config ) );
346
- assert( set_config != NULL );
347
-
348
- struct ofp_switch_config *switch_config = ( struct ofp_switch_config * ) set_config->data;
349
- switch_config->flags = htons( flags );
350
- switch_config->miss_send_len = htons( miss_send_len );
351
- return set_config;
352
- }
353
-
354
-
355
- buffer *
356
- create_packet_in( const uint32_t transaction_id, const uint32_t buffer_id, const uint16_t total_len,
357
- uint16_t in_port, const uint8_t reason, const buffer *data ) {
358
- uint16_t data_length = 0;
359
- buffer *buffer;
360
- struct ofp_packet_in *packet_in;
361
-
362
- if ( ( data != NULL ) && ( data->length > 0 ) ) {
363
- data_length = ( uint16_t ) data->length;
364
- }
365
-
366
- debug( "Creating a packet-in "
367
- "( xid = %#x, buffer_id = %#x, total_len = %u, "
368
- "in_port = %u, reason = %#x, data length = %u ).",
369
- transaction_id, buffer_id, total_len,
370
- in_port, reason, data_length );
371
-
372
- buffer = create_header( transaction_id, OFPT_PACKET_IN,
373
- ( uint16_t ) ( offsetof( struct ofp_packet_in, data ) + data_length ) );
374
- assert( buffer != NULL );
375
-
376
- packet_in = ( struct ofp_packet_in * ) buffer->data;
377
- packet_in->buffer_id = htonl( buffer_id );
378
- packet_in->total_len = htons( total_len );
379
- packet_in->in_port = htons( in_port );
380
- packet_in->reason = reason;
381
- packet_in->pad = 0;
382
-
383
- if ( data_length > 0 ) {
384
- memcpy( packet_in->data, data->data, data_length );
385
- }
386
-
387
- return buffer;
388
- }
389
-
390
-
391
- buffer *
392
- create_flow_removed( const uint32_t transaction_id, const struct ofp_match match,
393
- const uint64_t cookie, const uint16_t priority,
394
- const uint8_t reason, const uint32_t duration_sec,
395
- const uint32_t duration_nsec, const uint16_t idle_timeout,
396
- const uint64_t packet_count, const uint64_t byte_count ) {
397
- char match_str[ 1024 ];
398
- buffer *buffer;
399
- struct ofp_match m = match;
400
- struct ofp_flow_removed *flow_removed;
401
-
402
- // Because match_to_string() is costly, we check logging_level first.
403
- if ( get_logging_level() >= LOG_DEBUG ) {
404
- match_to_string( &m, match_str, sizeof( match_str ) );
405
- debug( "Creating a flow removed "
406
- "( xid = %#x, match = [%s], cookie = %#" PRIx64 ", priority = %u, "
407
- "reason = %#x, duration_sec = %u, duration_nsec = %u, "
408
- "idle_timeout = %u, packet_count = %" PRIu64 ", byte_count = %" PRIu64 " ).",
409
- transaction_id, match_str, cookie, priority,
410
- reason, duration_sec, duration_nsec,
411
- idle_timeout, packet_count, byte_count );
412
- }
413
-
414
- buffer = create_header( transaction_id, OFPT_FLOW_REMOVED, sizeof( struct ofp_flow_removed ) );
415
- assert( buffer != NULL );
416
-
417
- flow_removed = ( struct ofp_flow_removed * ) buffer->data;
418
- hton_match( &flow_removed->match, &m );
419
- flow_removed->cookie = htonll( cookie );
420
- flow_removed->priority = htons( priority );
421
- flow_removed->reason = reason;
422
- memset( &flow_removed->pad, 0, sizeof( flow_removed->pad ) );
423
- flow_removed->duration_sec = htonl( duration_sec );
424
- flow_removed->duration_nsec = htonl( duration_nsec );
425
- flow_removed->idle_timeout = htons( idle_timeout );
426
- memset( &flow_removed->pad2, 0, sizeof( flow_removed->pad2 ) );
427
- flow_removed->packet_count = htonll( packet_count );
428
- flow_removed->byte_count = htonll( byte_count );
429
-
430
- return buffer;
431
- }
432
-
433
-
434
- buffer *
435
- create_port_status( const uint32_t transaction_id, const uint8_t reason,
436
- const struct ofp_phy_port desc ) {
437
- char desc_str[ 1024 ];
438
- buffer *buffer;
439
- struct ofp_phy_port d = desc;
440
- struct ofp_port_status *port_status;
441
-
442
- phy_port_to_string( &d, desc_str, sizeof( desc_str ) );
443
- debug( "Creating a port status ( xid = %#x, reason = %#x, desc = [%s] ).",
444
- transaction_id, reason, desc_str );
445
-
446
- buffer = create_header( transaction_id, OFPT_PORT_STATUS, sizeof( struct ofp_port_status ) );
447
- assert( buffer != NULL );
448
-
449
- port_status = ( struct ofp_port_status * ) buffer->data;
450
- port_status->reason = reason;
451
- memset( &port_status->pad, 0, sizeof( port_status->pad ) );
452
- hton_phy_port( &port_status->desc, &d );
453
-
454
- return buffer;
455
- }
456
-
457
-
458
- static uint16_t
459
- get_actions_length( const openflow_actions *actions ) {
460
- int actions_length = 0;
461
- struct ofp_action_header *action_header;
462
- list_element *action;
463
-
464
- debug( "Calculating the total length of actions." );
465
-
466
- assert( actions != NULL );
467
-
468
- action = actions->list;
469
- while ( action != NULL ) {
470
- action_header = ( struct ofp_action_header * ) action->data;
471
-
472
- if ( ( action_header->type <= OFPAT_ENQUEUE ) || ( action_header->type == OFPAT_VENDOR ) ) {
473
- actions_length += action_header->len;
474
- }
475
- else {
476
- critical( "Undefined action type ( type = %#x ).", action_header->type );
477
- assert( 0 );
478
- }
479
-
480
- action = action->next;
481
- }
482
-
483
- debug( "Total length of actions = %d.", actions_length );
484
-
485
- if ( actions_length > UINT16_MAX ) {
486
- critical( "Too many actions ( # of actions = %d, actions length = %d ).",
487
- actions->n_actions, actions_length );
488
- assert( 0 );
489
- }
490
-
491
- return ( uint16_t ) actions_length;
492
- }
493
-
494
-
495
- buffer *
496
- create_packet_out( const uint32_t transaction_id, const uint32_t buffer_id, const uint16_t in_port,
497
- const openflow_actions *actions, const buffer *data ) {
498
- void *a, *d;
499
- uint16_t length;
500
- uint16_t data_length = 0;
501
- uint16_t action_length = 0;
502
- uint16_t actions_length = 0;
503
- buffer *buffer;
504
- struct ofp_packet_out *packet_out;
505
- struct ofp_action_header *action_header;
506
- list_element *action;
507
-
508
- if ( ( data != NULL ) && ( data->length > 0 ) ) {
509
- data_length = ( uint16_t ) data->length;
510
- }
511
-
512
- debug( "Creating a packet-out ( xid = %#x, buffer_id = %#x, in_port = %u, data length = %u ).",
513
- transaction_id, buffer_id, in_port, data_length );
514
-
515
- if ( buffer_id == UINT32_MAX ) {
516
- if ( data == NULL ) {
517
- die( "An Ethernet frame must be provided if buffer_id is equal to %#x", UINT32_MAX );
518
- }
519
- if ( data->length + ETH_FCS_LENGTH < ETH_MINIMUM_LENGTH ) {
520
- die( "The length of the provided Ethernet frame is shorter than the minimum length of an Ethernet frame (= %d bytes).", ETH_MINIMUM_LENGTH );
521
- }
522
- }
523
-
524
- if ( actions != NULL ) {
525
- debug( "# of actions = %d.", actions->n_actions );
526
- actions_length = get_actions_length( actions );
527
- }
528
-
529
- length = ( uint16_t ) ( offsetof( struct ofp_packet_out, actions ) + actions_length + data_length );
530
- buffer = create_header( transaction_id, OFPT_PACKET_OUT, length );
531
- assert( buffer != NULL );
532
-
533
- packet_out = ( struct ofp_packet_out * ) buffer->data;
534
- packet_out->buffer_id = htonl( buffer_id );
535
- packet_out->in_port = htons( in_port );
536
- packet_out->actions_len = htons( actions_length );
537
-
538
- if ( actions_length > 0 ) {
539
- a = ( void * ) ( ( char * ) buffer->data + offsetof( struct ofp_packet_out, actions ) );
540
-
541
- action = actions->list;
542
- while ( action != NULL ) {
543
- action_header = ( struct ofp_action_header * ) action->data;
544
- action_length = action_header->len;
545
- hton_action( ( struct ofp_action_header * ) a, action_header );
546
- a = ( void * ) ( ( char * ) a + action_length );
547
- action = action->next;
548
- }
549
- }
550
-
551
- if ( data_length > 0 ) {
552
- d = ( void * ) ( ( char * ) buffer->data
553
- + offsetof( struct ofp_packet_out, actions ) + actions_length );
554
- memcpy( d, data->data, data_length );
555
- }
556
-
557
- return buffer;
558
- }
559
-
560
-
561
- buffer *
562
- create_flow_mod( const uint32_t transaction_id, const struct ofp_match match,
563
- const uint64_t cookie, const uint16_t command,
564
- const uint16_t idle_timeout, const uint16_t hard_timeout,
565
- const uint16_t priority, const uint32_t buffer_id,
566
- const uint16_t out_port, const uint16_t flags,
567
- const openflow_actions *actions ) {
568
- void *a;
569
- char match_str[ 1024 ];
570
- uint16_t length;
571
- uint16_t action_length = 0;
572
- uint16_t actions_length = 0;
573
- buffer *buffer;
574
- struct ofp_match m = match;
575
- struct ofp_flow_mod *flow_mod;
576
- struct ofp_action_header *action_header;
577
- list_element *action;
578
-
579
- // Because match_to_string() is costly, we check logging_level first.
580
- if ( get_logging_level() >= LOG_DEBUG ) {
581
- match_to_string( &m, match_str, sizeof( match_str ) );
582
- debug( "Creating a flow modification "
583
- "( xid = %#x, match = [%s], cookie = %#" PRIx64 ", command = %#x, "
584
- "idle_timeout = %u, hard_timeout = %u, priority = %u, "
585
- "buffer_id = %#x, out_port = %u, flags = %#x ).",
586
- transaction_id, match_str, cookie, command,
587
- idle_timeout, hard_timeout, priority,
588
- buffer_id, out_port, flags );
589
- }
590
-
591
- if ( actions != NULL ) {
592
- debug( "# of actions = %d.", actions->n_actions );
593
- actions_length = get_actions_length( actions );
594
- }
595
-
596
- length = ( uint16_t ) ( offsetof( struct ofp_flow_mod, actions ) + actions_length );
597
- buffer = create_header( transaction_id, OFPT_FLOW_MOD, length );
598
- assert( buffer != NULL );
599
-
600
- flow_mod = ( struct ofp_flow_mod * ) buffer->data;
601
- hton_match( &flow_mod->match, &m );
602
- flow_mod->cookie = htonll( cookie );
603
- flow_mod->command = htons( command );
604
- flow_mod->idle_timeout = htons( idle_timeout );
605
- flow_mod->hard_timeout = htons( hard_timeout );
606
- flow_mod->priority = htons( priority );
607
- flow_mod->buffer_id = htonl( buffer_id );
608
- flow_mod->out_port = htons( out_port );
609
- flow_mod->flags = htons( flags );
610
-
611
- if ( actions_length > 0 ) {
612
- a = ( void * ) ( ( char * ) buffer->data + offsetof( struct ofp_flow_mod, actions ) );
613
-
614
- action = actions->list;
615
- while ( action != NULL ) {
616
- action_header = ( struct ofp_action_header * ) action->data;
617
- action_length = action_header->len;
618
- hton_action( ( struct ofp_action_header * ) a, action_header );
619
- a = ( void * ) ( ( char * ) a + action_length );
620
- action = action->next;
621
- }
622
- }
623
-
624
- return buffer;
625
- }
626
-
627
-
628
- buffer *
629
- create_port_mod( const uint32_t transaction_id, const uint16_t port_no,
630
- const uint8_t hw_addr[ OFP_ETH_ALEN ], const uint32_t config,
631
- const uint32_t mask, const uint32_t advertise ) {
632
- buffer *buffer;
633
- struct ofp_port_mod *port_mod;
634
-
635
- debug( "Creating a port modification "
636
- "( xid = %#x, port_no = %u, hw_addr = %02x:%02x:%02x:%02x:%02x:%02x, "
637
- "config = %#x, mask = %#x, advertise = %#x ).",
638
- transaction_id, port_no,
639
- hw_addr[ 0 ], hw_addr[ 1 ], hw_addr[ 2 ], hw_addr[ 3 ], hw_addr[ 4 ], hw_addr[ 5 ],
640
- config, mask, advertise );
641
-
642
- buffer = create_header( transaction_id, OFPT_PORT_MOD, sizeof( struct ofp_port_mod ) );
643
- assert( buffer != NULL );
644
-
645
- port_mod = ( struct ofp_port_mod * ) buffer->data;
646
- port_mod->port_no = htons( port_no );
647
- memcpy( port_mod->hw_addr, hw_addr, OFP_ETH_ALEN );
648
- port_mod->config = htonl( config );
649
- port_mod->mask = htonl( mask );
650
- port_mod->advertise = htonl( advertise );
651
- memset( port_mod->pad, 0, sizeof( port_mod->pad ) );
652
-
653
- return buffer;
654
- }
655
-
656
-
657
- static buffer *
658
- create_stats_request( const uint32_t transaction_id, const uint16_t type,
659
- const uint16_t length, const uint16_t flags ) {
660
- buffer *buffer;
661
- struct ofp_stats_request *stats_request;
662
-
663
- debug( "Creating a stats request ( xid = %#x, type = %#x, length = %u, flags = %#x ).",
664
- transaction_id, type, length, flags );
665
-
666
- buffer = create_header( transaction_id, OFPT_STATS_REQUEST, length );
667
- assert( buffer != NULL );
668
-
669
- stats_request = ( struct ofp_stats_request * ) buffer->data;
670
- stats_request->type = htons( type );
671
- stats_request->flags = htons( flags );
672
-
673
- return buffer;
674
- }
675
-
676
-
677
- buffer *
678
- create_desc_stats_request( const uint32_t transaction_id, const uint16_t flags ) {
679
- debug( "Creating a description stats request ( xid = %#x, flags = %#x ).",
680
- transaction_id, flags );
681
-
682
- return create_stats_request( transaction_id, OFPST_DESC,
683
- sizeof( struct ofp_stats_request ), flags );
684
- }
685
-
686
-
687
- buffer *
688
- create_flow_stats_request( const uint32_t transaction_id, const uint16_t flags,
689
- const struct ofp_match match, const uint8_t table_id,
690
- const uint16_t out_port ) {
691
- char match_str[ 1024 ];
692
- uint16_t length;
693
- buffer *buffer;
694
- struct ofp_match m = match;
695
- struct ofp_flow_stats_request *flow_stats_request;
696
-
697
- // Because match_to_string() is costly, we check logging_level first.
698
- if ( get_logging_level() >= LOG_DEBUG ) {
699
- match_to_string( &m, match_str, sizeof( match_str ) );
700
- debug( "Creating a flow stats request ( xid = %#x, flags = %#x, match = [%s], table_id = %u, out_port = %u ).",
701
- transaction_id, flags, match_str, table_id, out_port );
702
- }
703
-
704
- length = ( uint16_t ) ( offsetof( struct ofp_stats_request, body )
705
- + sizeof( struct ofp_flow_stats_request ) );
706
- buffer = create_stats_request( transaction_id, OFPST_FLOW, length, flags );
707
- assert( buffer != NULL );
708
-
709
- flow_stats_request = ( struct ofp_flow_stats_request * ) ( ( char * ) buffer->data
710
- + offsetof( struct ofp_stats_request, body ) );
711
- hton_match( &flow_stats_request->match, &m );
712
- flow_stats_request->table_id = table_id;
713
- flow_stats_request->pad = 0;
714
- flow_stats_request->out_port = htons( out_port );
715
-
716
- return buffer;
717
- }
718
-
719
-
720
- buffer *
721
- create_aggregate_stats_request( const uint32_t transaction_id,
722
- const uint16_t flags, const struct ofp_match match,
723
- const uint8_t table_id, const uint16_t out_port ) {
724
- char match_str[ 1024 ];
725
- uint16_t length;
726
- buffer *buffer;
727
- struct ofp_match m = match;
728
- struct ofp_aggregate_stats_request *aggregate_stats_request;
729
-
730
- // Because match_to_string() is costly, we check logging_level first.
731
- if ( get_logging_level() >= LOG_DEBUG ) {
732
- match_to_string( &m, match_str, sizeof( match_str ) );
733
- debug( "Creating an aggregate stats request ( xid = %#x, flags = %#x, match = [%s], table_id = %u, out_port = %u ).",
734
- transaction_id, flags, match_str, table_id, out_port );
735
- }
736
-
737
- length = ( uint16_t ) ( offsetof( struct ofp_stats_request, body )
738
- + sizeof( struct ofp_aggregate_stats_request ) );
739
- buffer = create_stats_request( transaction_id, OFPST_AGGREGATE, length, flags );
740
- assert( buffer != NULL );
741
-
742
- aggregate_stats_request = ( struct ofp_aggregate_stats_request * ) ( ( char * ) buffer->data
743
- + offsetof( struct ofp_stats_request, body ) );
744
- hton_match( &aggregate_stats_request->match, &m );
745
- aggregate_stats_request->table_id = table_id;
746
- aggregate_stats_request->pad = 0;
747
- aggregate_stats_request->out_port = htons( out_port );
748
-
749
- return buffer;
750
- }
751
-
752
-
753
- buffer *
754
- create_table_stats_request( const uint32_t transaction_id, const uint16_t flags ) {
755
- debug( "Creating a table stats request ( xid = %#x, flags = %#x ).", transaction_id, flags );
756
-
757
- return create_stats_request( transaction_id, OFPST_TABLE,
758
- sizeof( struct ofp_stats_request ), flags );
759
- }
760
-
761
-
762
- buffer *
763
- create_port_stats_request( const uint32_t transaction_id, const uint16_t flags,
764
- const uint16_t port_no ) {
765
- uint16_t length;
766
- buffer *buffer;
767
- struct ofp_port_stats_request *port_stats_request;
768
-
769
- debug( "Creating a port stats request ( xid = %#x, flags = %#x, port_no = %u ).",
770
- transaction_id, flags, port_no );
771
-
772
- length = ( uint16_t ) ( offsetof( struct ofp_stats_request, body )
773
- + sizeof( struct ofp_port_stats_request ) );
774
- buffer = create_stats_request( transaction_id, OFPST_PORT, length, flags );
775
- assert( buffer != NULL );
776
-
777
- port_stats_request = ( struct ofp_port_stats_request * ) ( ( char * ) buffer->data
778
- + offsetof( struct ofp_stats_request, body ) );
779
- port_stats_request->port_no = htons( port_no );
780
- memset( &port_stats_request->pad, 0, sizeof( port_stats_request->pad ) );
781
-
782
- return buffer;
783
- }
784
-
785
-
786
- buffer *
787
- create_queue_stats_request( const uint32_t transaction_id, const uint16_t flags,
788
- const uint16_t port_no, const uint32_t queue_id ) {
789
- uint16_t length;
790
- buffer *buffer;
791
- struct ofp_queue_stats_request *queue_stats_request;
792
-
793
- debug( "Creating a queue stats request ( xid = %#x, flags = %#x, port_no = %u, queue_id = %u ).",
794
- transaction_id, flags, port_no, queue_id );
795
-
796
- length = ( uint16_t ) ( offsetof( struct ofp_stats_request, body )
797
- + sizeof( struct ofp_queue_stats_request ) );
798
- buffer = create_stats_request( transaction_id, OFPST_QUEUE, length, flags );
799
- assert( buffer != NULL );
800
-
801
- queue_stats_request = ( struct ofp_queue_stats_request * ) ( ( char * ) buffer->data
802
- + offsetof( struct ofp_stats_request, body ) );
803
- queue_stats_request->port_no = htons( port_no );
804
- memset( &queue_stats_request->pad, 0, sizeof( queue_stats_request->pad ) );
805
- queue_stats_request->queue_id = htonl( queue_id );
806
-
807
- return buffer;
808
- }
809
-
810
-
811
- buffer *
812
- create_vendor_stats_request( const uint32_t transaction_id, const uint16_t flags,
813
- const uint32_t vendor, const buffer *body ) {
814
- void *b;
815
- uint16_t length;
816
- uint16_t data_length = 0;
817
- uint32_t *v;
818
- buffer *buffer;
819
-
820
- if ( ( body != NULL ) && ( body->length > 0 ) ) {
821
- data_length = ( uint16_t ) body->length;
822
- }
823
-
824
- debug( "Creating a vendor stats request ( xid = %#x, flags = %#x, vendor = %#x, data length = %u ).",
825
- transaction_id, flags, vendor, data_length );
826
-
827
- length = ( uint16_t ) ( offsetof( struct ofp_stats_request, body ) + sizeof( uint32_t )
828
- + data_length );
829
- buffer = create_stats_request( transaction_id, OFPST_VENDOR, length, flags );
830
- assert( buffer != NULL );
831
-
832
- v = ( uint32_t * ) ( ( char * ) buffer->data + offsetof( struct ofp_stats_request, body ) );
833
- *v = htonl( vendor );
834
-
835
- if ( data_length > 0 ) {
836
- b = ( void * ) ( ( char * ) buffer->data
837
- + offsetof( struct ofp_stats_request, body ) + sizeof( uint32_t ) );
838
-
839
- memcpy( b, body->data, data_length );
840
- }
841
-
842
- return buffer;
843
- }
844
-
845
-
846
- static buffer *
847
- create_stats_reply( const uint32_t transaction_id, const uint16_t type,
848
- const uint16_t length, const uint16_t flags ) {
849
- buffer *buffer;
850
- struct ofp_stats_reply *stats_reply;
851
-
852
- debug( "Creating a stats reply ( xid = %#x, type = %#x, length = %u, flags = %#x ).",
853
- transaction_id, type, length, flags );
854
-
855
- buffer = create_header( transaction_id, OFPT_STATS_REPLY, length );
856
- assert( buffer != NULL );
857
-
858
- stats_reply = ( struct ofp_stats_reply * ) buffer->data;
859
- stats_reply->type = htons( type );
860
- stats_reply->flags = htons( flags );
861
-
862
- return buffer;
863
- }
864
-
865
-
866
- buffer *
867
- create_desc_stats_reply( const uint32_t transaction_id, const uint16_t flags,
868
- const char mfr_desc[ DESC_STR_LEN ],
869
- const char hw_desc[ DESC_STR_LEN ],
870
- const char sw_desc[ DESC_STR_LEN ],
871
- const char serial_num[ SERIAL_NUM_LEN ],
872
- const char dp_desc[ DESC_STR_LEN ] ) {
873
- uint16_t length;
874
- buffer *buffer;
875
- struct ofp_stats_reply *stats_reply;
876
- struct ofp_desc_stats *desc_stats;
877
-
878
- debug( "Creating a description stats reply "
879
- "( xid = %#x, flags = %#x, mfr_desc = %s, hw_desc = %s, sw_desc = %s, serial_num = %s, dp_desc = %s ).",
880
- transaction_id, flags, mfr_desc, hw_desc, sw_desc, serial_num, dp_desc );
881
-
882
- length = ( uint16_t ) ( offsetof( struct ofp_stats_reply, body )
883
- + sizeof( struct ofp_desc_stats ) );
884
- buffer = create_stats_reply( transaction_id, OFPST_DESC, length, flags );
885
- assert( buffer != NULL );
886
-
887
- stats_reply = ( struct ofp_stats_reply * ) buffer->data;
888
- desc_stats = ( struct ofp_desc_stats * ) stats_reply->body;
889
- memcpy( desc_stats->mfr_desc, mfr_desc, DESC_STR_LEN );
890
- memcpy( desc_stats->hw_desc, hw_desc, DESC_STR_LEN );
891
- memcpy( desc_stats->sw_desc, sw_desc, DESC_STR_LEN );
892
- memcpy( desc_stats->serial_num, serial_num, DESC_STR_LEN );
893
- memcpy( desc_stats->dp_desc, dp_desc, DESC_STR_LEN );
894
-
895
- return buffer;
896
- }
897
-
898
-
899
- buffer *
900
- create_flow_stats_reply( const uint32_t transaction_id, const uint16_t flags,
901
- const list_element *flows_stats_head ) {
902
- int n_flows = 0;
903
- uint16_t length = 0;
904
- buffer *buffer;
905
- list_element *f = NULL;
906
- list_element *flow = NULL;
907
- struct ofp_stats_reply *stats_reply;
908
- struct ofp_flow_stats *fs, *flow_stats;
909
-
910
- debug( "Creating a flow stats reply ( xid = %#x, flags = %#x ).", transaction_id, flags );
911
-
912
- if ( flows_stats_head != NULL ) {
913
- f = ( list_element * ) xmalloc( sizeof( list_element ) );
914
- memcpy( f, flows_stats_head, sizeof( list_element ) );
915
- }
916
-
917
- flow = f;
918
- while ( flow != NULL ) {
919
- flow_stats = flow->data;
920
- length = ( uint16_t ) ( length + flow_stats->length );
921
- n_flows++;
922
- flow = flow->next;
923
- }
924
-
925
- debug( "# of flows = %d.", n_flows );
926
-
927
- length = ( uint16_t ) ( offsetof( struct ofp_stats_reply, body ) + length );
928
-
929
- buffer = create_stats_reply( transaction_id, OFPST_FLOW, length, flags );
930
- assert( buffer != NULL );
931
-
932
- stats_reply = ( struct ofp_stats_reply * ) buffer->data;
933
- flow_stats = ( struct ofp_flow_stats * ) stats_reply->body;
934
-
935
- flow = f;
936
- while ( flow != NULL ) {
937
- fs = ( struct ofp_flow_stats * ) flow->data;
938
- hton_flow_stats( flow_stats, fs );
939
- flow_stats = ( struct ofp_flow_stats * ) ( ( char * ) flow_stats + fs->length );
940
- flow = flow->next;
941
- }
942
-
943
- if ( f != NULL ) {
944
- xfree( f );
945
- }
946
-
947
- return buffer;
948
- }
949
-
950
-
951
- buffer *
952
- create_aggregate_stats_reply( const uint32_t transaction_id, const uint16_t flags,
953
- const uint64_t packet_count, const uint64_t byte_count,
954
- const uint32_t flow_count ) {
955
- uint16_t length;
956
- buffer *buffer;
957
- struct ofp_stats_reply *stats_reply;
958
- struct ofp_aggregate_stats_reply *aggregate_stats_reply;
959
-
960
- debug( "Creating an aggregate stats reply "
961
- "( xid = %#x, flags = %#x, packet_count = %" PRIu64 ", byte_count = %" PRIu64 ", flow_count = %u ).",
962
- transaction_id, flags, packet_count, byte_count, flow_count );
963
-
964
- length = ( uint16_t ) ( offsetof( struct ofp_stats_reply, body )
965
- + sizeof( struct ofp_aggregate_stats_reply ) );
966
- buffer = create_stats_reply( transaction_id, OFPST_AGGREGATE, length, flags );
967
- assert( buffer != NULL );
968
-
969
- stats_reply = ( struct ofp_stats_reply * ) buffer->data;
970
- aggregate_stats_reply = ( struct ofp_aggregate_stats_reply * ) stats_reply->body;
971
- aggregate_stats_reply->packet_count = htonll( packet_count );
972
- aggregate_stats_reply->byte_count = htonll( byte_count );
973
- aggregate_stats_reply->flow_count = htonl( flow_count );
974
- memset( &aggregate_stats_reply->pad, 0, sizeof( aggregate_stats_reply->pad ) );
975
-
976
- return buffer;
977
- }
978
-
979
-
980
- buffer *
981
- create_table_stats_reply( const uint32_t transaction_id, const uint16_t flags,
982
- const list_element *table_stats_head ) {
983
- uint16_t length;
984
- uint16_t n_tables = 0;
985
- buffer *buffer;
986
- list_element *t = NULL;
987
- list_element *table = NULL;
988
- struct ofp_stats_reply *stats_reply;
989
- struct ofp_table_stats *ts, *table_stats;
990
-
991
- debug( "Creating a table stats reply ( xid = %#x, flags = %#x ).", transaction_id, flags );
992
-
993
- if ( table_stats_head != NULL ) {
994
- t = ( list_element * ) xmalloc( sizeof( list_element ) );
995
- memcpy( t, table_stats_head, sizeof( list_element ) );
996
- }
997
-
998
- table = t;
999
- while ( table != NULL ) {
1000
- n_tables++;
1001
- table = table->next;
1002
- }
1003
-
1004
- debug( "# of tables = %u.", n_tables );
1005
-
1006
- length = ( uint16_t ) ( offsetof( struct ofp_stats_reply, body )
1007
- + sizeof( struct ofp_table_stats ) * n_tables );
1008
- buffer = create_stats_reply( transaction_id, OFPST_TABLE, length, flags );
1009
- assert( buffer != NULL );
1010
-
1011
- stats_reply = ( struct ofp_stats_reply * ) buffer->data;
1012
- table_stats = ( struct ofp_table_stats * ) stats_reply->body;
1013
-
1014
- table = t;
1015
- while ( table != NULL ) {
1016
- ts = ( struct ofp_table_stats * ) table->data;
1017
- hton_table_stats( table_stats, ts );
1018
- table = table->next;
1019
- table_stats++;
1020
- }
1021
-
1022
- if ( t != NULL ) {
1023
- xfree( t );
1024
- }
1025
-
1026
- return buffer;
1027
- }
1028
-
1029
-
1030
- buffer *
1031
- create_port_stats_reply( const uint32_t transaction_id, const uint16_t flags,
1032
- const list_element *port_stats_head ) {
1033
- uint16_t length;
1034
- uint16_t n_ports = 0;
1035
- buffer *buffer;
1036
- list_element *p = NULL;
1037
- list_element *port = NULL;
1038
- struct ofp_stats_reply *stats_reply;
1039
- struct ofp_port_stats *ps, *port_stats;
1040
-
1041
- debug( "Creating a port stats reply ( xid = %#x, flags = %#x ).", transaction_id, flags );
1042
-
1043
- if ( port_stats_head != NULL ) {
1044
- p = ( list_element * ) xmalloc( sizeof( list_element ) );
1045
- memcpy( p, port_stats_head, sizeof( list_element ) );
1046
- }
1047
-
1048
- port = p;
1049
- while ( port != NULL ) {
1050
- n_ports++;
1051
- port = port->next;
1052
- }
1053
-
1054
- debug( "# of ports = %u.", n_ports );
1055
-
1056
- length = ( uint16_t ) ( offsetof( struct ofp_stats_reply, body )
1057
- + sizeof( struct ofp_port_stats ) * n_ports );
1058
- buffer = create_stats_reply( transaction_id, OFPST_PORT, length, flags );
1059
- assert( buffer != NULL );
1060
-
1061
- stats_reply = ( struct ofp_stats_reply * ) buffer->data;
1062
- port_stats = ( struct ofp_port_stats * ) stats_reply->body;
1063
-
1064
- port = p;
1065
- while ( port != NULL ) {
1066
- ps = ( struct ofp_port_stats * ) port->data;
1067
- hton_port_stats( port_stats, ps );
1068
- port = port->next;
1069
- port_stats++;
1070
- }
1071
-
1072
- if ( p != NULL ) {
1073
- xfree( p );
1074
- }
1075
-
1076
- return buffer;
1077
- }
1078
-
1079
-
1080
- buffer *
1081
- create_queue_stats_reply( const uint32_t transaction_id, const uint16_t flags,
1082
- const list_element *queue_stats_head ) {
1083
- uint16_t length;
1084
- uint16_t n_queues = 0;
1085
- buffer *buffer;
1086
- list_element *q = NULL;
1087
- list_element *queue = NULL;
1088
- struct ofp_stats_reply *stats_reply;
1089
- struct ofp_queue_stats *qs, *queue_stats;
1090
-
1091
- debug( "Creating a queue stats reply ( xid = %#x, flags = %#x ).", transaction_id, flags );
1092
-
1093
- if ( queue_stats_head != NULL ) {
1094
- q = ( list_element * ) xmalloc( sizeof( list_element ) );
1095
- memcpy( q, queue_stats_head, sizeof( list_element ) );
1096
- }
1097
-
1098
- queue = q;
1099
- while ( queue != NULL ) {
1100
- n_queues++;
1101
- queue = queue->next;
1102
- }
1103
-
1104
- debug( "# of queues = %u.", n_queues );
1105
-
1106
- length = ( uint16_t ) ( offsetof( struct ofp_stats_reply, body )
1107
- + sizeof( struct ofp_queue_stats ) * n_queues );
1108
- buffer = create_stats_reply( transaction_id, OFPST_QUEUE, length, flags );
1109
- assert( buffer != NULL );
1110
-
1111
- stats_reply = ( struct ofp_stats_reply * ) buffer->data;
1112
- queue_stats = ( struct ofp_queue_stats * ) stats_reply->body;
1113
-
1114
- queue = q;
1115
- while ( queue != NULL ) {
1116
- qs = ( struct ofp_queue_stats * ) queue->data;
1117
- hton_queue_stats( queue_stats, qs );
1118
- queue = queue->next;
1119
- queue_stats++;
1120
- }
1121
-
1122
- if ( q != NULL ) {
1123
- xfree( q );
1124
- }
1125
-
1126
- return buffer;
1127
- }
1128
-
1129
-
1130
- buffer *
1131
- create_vendor_stats_reply( const uint32_t transaction_id, const uint16_t flags,
1132
- const uint32_t vendor, const buffer *body ) {
1133
- void *b;
1134
- uint16_t length;
1135
- uint16_t data_length = 0;
1136
- uint32_t *v;
1137
- buffer *buffer;
1138
- struct ofp_stats_reply *stats_reply;
1139
-
1140
- if ( ( body != NULL ) && ( body->length > 0 ) ) {
1141
- data_length = ( uint16_t ) body->length;
1142
- }
1143
-
1144
- debug( "Creating a vendor stats reply ( xid = %#x, flags = %#x, vendor = %#x, data length = %u ).",
1145
- transaction_id, flags, vendor, data_length );
1146
-
1147
- length = ( uint16_t ) ( offsetof( struct ofp_stats_reply, body )
1148
- + sizeof( uint32_t ) + data_length );
1149
- buffer = create_stats_reply( transaction_id, OFPST_VENDOR, length, flags );
1150
- assert( buffer != NULL );
1151
-
1152
- stats_reply = ( struct ofp_stats_reply * ) buffer->data;
1153
- v = ( uint32_t * ) stats_reply->body;
1154
- *v = htonl( vendor );
1155
-
1156
- if ( data_length > 0 ) {
1157
- b = ( void * ) ( ( char * ) v + sizeof( uint32_t ) );
1158
- memcpy( b, body->data, data_length );
1159
- }
1160
-
1161
- return buffer;
1162
- }
1163
-
1164
-
1165
- buffer *
1166
- create_barrier_request( const uint32_t transaction_id ) {
1167
- debug( "Creating a barrier request ( xid = %#x ).", transaction_id );
1168
-
1169
- return create_header( transaction_id, OFPT_BARRIER_REQUEST, sizeof( struct ofp_header ) );
1170
- }
1171
-
1172
-
1173
- buffer *
1174
- create_barrier_reply( const uint32_t transaction_id ) {
1175
- debug( "Creating a barrier reply ( xid = %#x ).", transaction_id );
1176
-
1177
- return create_header( transaction_id, OFPT_BARRIER_REPLY, sizeof( struct ofp_header ) );
1178
- }
1179
-
1180
-
1181
- buffer *
1182
- create_queue_get_config_request( const uint32_t transaction_id, const uint16_t port ) {
1183
- buffer *buffer;
1184
- struct ofp_queue_get_config_request *queue_get_config_request;
1185
-
1186
- debug( "Creating a queue get config request ( xid = %#x, port = %u ).", transaction_id, port );
1187
-
1188
- buffer = create_header( transaction_id, OFPT_QUEUE_GET_CONFIG_REQUEST,
1189
- sizeof( struct ofp_queue_get_config_request ) );
1190
- assert( buffer != NULL );
1191
-
1192
- queue_get_config_request = ( struct ofp_queue_get_config_request * ) buffer->data;
1193
- queue_get_config_request->port = htons( port );
1194
- memset( queue_get_config_request->pad, 0, sizeof( queue_get_config_request->pad ) );
1195
-
1196
- return buffer;
1197
- }
1198
-
1199
-
1200
- buffer *
1201
- create_queue_get_config_reply( const uint32_t transaction_id, const uint16_t port,
1202
- const list_element *queues ) {
1203
- uint16_t length;
1204
- uint16_t n_queues = 0;
1205
- uint16_t queues_length = 0;
1206
- buffer *buffer;
1207
- list_element *q, *queue;
1208
- struct ofp_queue_get_config_reply *queue_get_config_reply;
1209
- struct ofp_packet_queue *pq, *packet_queue;
1210
-
1211
- debug( "Creating a queue get config reply ( xid = %#x, port = %u ).", transaction_id, port );
1212
-
1213
- #ifndef UNIT_TESTING
1214
- assert( queues != NULL );
1215
- #endif
1216
-
1217
- if ( queues != NULL ) {
1218
- q = ( list_element * ) xmalloc( sizeof( list_element ) );
1219
- memcpy( q, queues, sizeof( list_element ) );
1220
-
1221
- queue = q;
1222
- while ( queue != NULL ) {
1223
- packet_queue = ( struct ofp_packet_queue * ) queue->data;
1224
- queues_length = ( uint16_t ) ( queues_length + packet_queue->len );
1225
- n_queues++;
1226
- queue = queue->next;
1227
- }
1228
- }
1229
-
1230
- debug( "# of queues = %u.", n_queues );
1231
-
1232
- length = ( uint16_t ) ( offsetof( struct ofp_queue_get_config_reply, queues ) + queues_length );
1233
- buffer = create_header( transaction_id, OFPT_QUEUE_GET_CONFIG_REPLY, length );
1234
- assert( buffer != NULL );
1235
-
1236
- queue_get_config_reply = ( struct ofp_queue_get_config_reply * ) buffer->data;
1237
- queue_get_config_reply->port = htons( port );
1238
- memset( &queue_get_config_reply->pad, 0, sizeof( queue_get_config_reply->pad ) );
1239
- packet_queue = ( struct ofp_packet_queue * ) queue_get_config_reply->queues;
1240
-
1241
- if ( n_queues ) {
1242
- queue = q;
1243
- while ( queue != NULL ) {
1244
- pq = ( struct ofp_packet_queue * ) queue->data;
1245
-
1246
- hton_packet_queue( packet_queue, pq );
1247
-
1248
- packet_queue = ( struct ofp_packet_queue * ) ( ( char * ) packet_queue + pq->len );
1249
- queue = queue->next;
1250
- }
1251
-
1252
- xfree( q );
1253
- }
1254
-
1255
- return buffer;
1256
- }
1257
-
1258
-
1259
- uint32_t
1260
- get_transaction_id( void ) {
1261
- debug( "Generating a transaction id." );
1262
-
1263
- pthread_mutex_lock( &transaction_id_mutex );
1264
-
1265
- if ( ( transaction_id & 0xffff ) == 0xffff ) {
1266
- transaction_id = transaction_id & 0xffff0000;
1267
- }
1268
- else {
1269
- transaction_id++;
1270
- }
1271
-
1272
- pthread_mutex_unlock( &transaction_id_mutex );
1273
-
1274
- debug( "Transaction id = %#x.", transaction_id );
1275
-
1276
- return transaction_id;
1277
- }
1278
-
1279
-
1280
- uint64_t
1281
- get_cookie( void ) {
1282
- debug( "Generating a cookie." );
1283
-
1284
- pthread_mutex_lock( &cookie_mutex );
1285
-
1286
- if ( ( cookie & 0x0000ffffffffffffULL ) == 0x0000ffffffffffffULL ) {
1287
- cookie = cookie & 0xffff000000000000ULL;
1288
- }
1289
- else {
1290
- cookie++;
1291
- }
1292
-
1293
- pthread_mutex_unlock( &cookie_mutex );
1294
-
1295
- debug( "Cookie = %#" PRIx64 ".", cookie );
1296
-
1297
- return cookie;
1298
- }
1299
-
1300
-
1301
- openflow_actions *
1302
- create_actions() {
1303
- openflow_actions *actions;
1304
-
1305
- debug( "Creating an empty actions list." );
1306
-
1307
- actions = ( openflow_actions * ) xmalloc( sizeof( openflow_actions ) );
1308
-
1309
- if ( create_list( &actions->list ) == false ) {
1310
- assert( 0 );
1311
- }
1312
-
1313
- actions->n_actions = 0;
1314
-
1315
- return actions;
1316
- }
1317
-
1318
-
1319
- bool
1320
- delete_actions( openflow_actions *actions ) {
1321
- list_element *element;
1322
-
1323
- debug( "Deleting an actions list." );
1324
-
1325
- assert( actions != NULL );
1326
-
1327
- debug( "# of actions = %d.", actions->n_actions );
1328
-
1329
- element = actions->list;
1330
- while ( element != NULL ) {
1331
- xfree( element->data );
1332
- element = element->next;
1333
- }
1334
-
1335
- delete_list( actions->list );
1336
- xfree( actions );
1337
-
1338
- return true;
1339
- }
1340
-
1341
-
1342
- bool
1343
- append_action_output( openflow_actions *actions, const uint16_t port, const uint16_t max_len ) {
1344
- bool ret;
1345
- struct ofp_action_output *action_output;
1346
-
1347
- debug( "Appending an output action ( port = %u, max_len = %u ).", port, max_len );
1348
-
1349
- assert( actions != NULL );
1350
-
1351
- action_output = ( struct ofp_action_output * ) xcalloc( 1, sizeof( struct ofp_action_output ) );
1352
- action_output->type = OFPAT_OUTPUT;
1353
- action_output->len = sizeof( struct ofp_action_output );
1354
- action_output->port = port;
1355
- action_output->max_len = max_len;
1356
-
1357
- ret = append_to_tail( &actions->list, ( void * ) action_output );
1358
- if ( ret ) {
1359
- actions->n_actions++;
1360
- }
1361
-
1362
- return ret;
1363
- }
1364
-
1365
-
1366
- bool
1367
- append_action_set_vlan_vid( openflow_actions *actions, const uint16_t vlan_vid ) {
1368
- bool ret;
1369
- struct ofp_action_vlan_vid *action_vlan_vid;
1370
-
1371
- debug( "Appending a set vlan action ( vlan_vid = %#x ).", vlan_vid );
1372
-
1373
- assert( actions != NULL );
1374
- assert( ( vlan_vid & ~VLAN_VID_MASK ) == 0 );
1375
-
1376
- action_vlan_vid = ( struct ofp_action_vlan_vid * ) xcalloc( 1, sizeof( struct ofp_action_vlan_vid ) );
1377
- action_vlan_vid->type = OFPAT_SET_VLAN_VID;
1378
- action_vlan_vid->len = sizeof( struct ofp_action_vlan_vid );
1379
- action_vlan_vid->vlan_vid = vlan_vid;
1380
-
1381
- ret = append_to_tail( &actions->list, ( void * ) action_vlan_vid );
1382
- if ( ret ) {
1383
- actions->n_actions++;
1384
- }
1385
-
1386
- return ret;
1387
- }
1388
-
1389
-
1390
- bool
1391
- append_action_set_vlan_pcp( openflow_actions *actions, const uint8_t vlan_pcp ) {
1392
- bool ret;
1393
- struct ofp_action_vlan_pcp *action_vlan_pcp;
1394
-
1395
- debug( "Appending a set vlan pcp action ( vlan_pcp = %#x ).", vlan_pcp );
1396
-
1397
- assert( actions != NULL );
1398
- assert( ( vlan_pcp & ~VLAN_PCP_MASK ) == 0 );
1399
-
1400
- action_vlan_pcp = ( struct ofp_action_vlan_pcp * ) xcalloc( 1, sizeof( struct ofp_action_vlan_pcp ) );
1401
- action_vlan_pcp->type = OFPAT_SET_VLAN_PCP;
1402
- action_vlan_pcp->len = sizeof( struct ofp_action_vlan_pcp );
1403
- action_vlan_pcp->vlan_pcp = vlan_pcp;
1404
-
1405
- ret = append_to_tail( &actions->list, ( void * ) action_vlan_pcp );
1406
- if ( ret ) {
1407
- actions->n_actions++;
1408
- }
1409
-
1410
- return ret;
1411
- }
1412
-
1413
-
1414
- bool
1415
- append_action_strip_vlan( openflow_actions *actions ) {
1416
- bool ret;
1417
- struct ofp_action_header *action_strip_vlan;
1418
-
1419
- debug( "Appending a strip vlan action." );
1420
-
1421
- assert( actions != NULL );
1422
-
1423
- action_strip_vlan = ( struct ofp_action_header * ) xcalloc( 1, sizeof( struct ofp_action_header ) );
1424
- action_strip_vlan->type = OFPAT_STRIP_VLAN;
1425
- action_strip_vlan->len = sizeof( struct ofp_action_header );
1426
-
1427
- ret = append_to_tail( &actions->list, ( void * ) action_strip_vlan );
1428
- if ( ret ) {
1429
- actions->n_actions++;
1430
- }
1431
-
1432
- return ret;
1433
- }
1434
-
1435
-
1436
- static bool
1437
- append_action_set_dl_addr( openflow_actions *actions, const uint16_t type,
1438
- const uint8_t hw_addr[ OFP_ETH_ALEN ] ) {
1439
- bool ret;
1440
- struct ofp_action_dl_addr *action_dl_addr;
1441
-
1442
- debug( "Appending a set dl_src/dl_dst action ( type = %#x, hw_addr = %02x:%02x:%02x:%02x:%02x:%02x ).",
1443
- type, hw_addr[ 0 ], hw_addr[ 1 ], hw_addr[ 2 ], hw_addr[ 3 ], hw_addr[ 4 ], hw_addr[ 5 ] );
1444
-
1445
- assert( actions != NULL );
1446
-
1447
- action_dl_addr = ( struct ofp_action_dl_addr * ) xcalloc( 1, sizeof( struct ofp_action_dl_addr ) );
1448
- action_dl_addr->type = type;
1449
- action_dl_addr->len = sizeof( struct ofp_action_dl_addr );
1450
- memcpy( action_dl_addr->dl_addr, hw_addr, OFP_ETH_ALEN );
1451
-
1452
- ret = append_to_tail( &actions->list, ( void * ) action_dl_addr );
1453
- if ( ret ) {
1454
- actions->n_actions++;
1455
- }
1456
-
1457
- return ret;
1458
- }
1459
-
1460
-
1461
- bool
1462
- append_action_set_dl_src( openflow_actions *actions, const uint8_t hw_addr[ OFP_ETH_ALEN ] ) {
1463
- debug( "Appending a set dl_src action ( hw_addr = %02x:%02x:%02x:%02x:%02x:%02x ).",
1464
- hw_addr[ 0 ], hw_addr[ 1 ], hw_addr[ 2 ], hw_addr[ 3 ], hw_addr[ 4 ], hw_addr[ 5 ] );
1465
-
1466
- assert( actions != NULL );
1467
- return append_action_set_dl_addr( actions, OFPAT_SET_DL_SRC, hw_addr );
1468
- }
1469
-
1470
-
1471
- bool
1472
- append_action_set_dl_dst( openflow_actions *actions, const uint8_t hw_addr[ OFP_ETH_ALEN ] ) {
1473
- debug( "Appending a set dl_dst action ( hw_addr = %02x:%02x:%02x:%02x:%02x:%02x ).",
1474
- hw_addr[ 0 ], hw_addr[ 1 ], hw_addr[ 2 ], hw_addr[ 3 ], hw_addr[ 4 ], hw_addr[ 5 ] );
1475
-
1476
- assert( actions != NULL );
1477
- return append_action_set_dl_addr( actions, OFPAT_SET_DL_DST, hw_addr );
1478
- }
1479
-
1480
-
1481
- static bool
1482
- append_action_set_nw_addr( openflow_actions *actions, const uint16_t type, const uint32_t nw_addr ) {
1483
- bool ret;
1484
- char addr_str[ 16 ];
1485
- struct in_addr addr;
1486
- struct ofp_action_nw_addr *action_nw_addr;
1487
-
1488
- addr.s_addr = htonl( nw_addr );
1489
- memset( addr_str, '\0', sizeof( addr_str ) );
1490
- inet_ntop( AF_INET, &addr, addr_str, sizeof( addr_str ) );
1491
- debug( "Appending a set nw_src/nw_dst action ( type = %#x, nw_addr = %s ).", type, addr_str );
1492
-
1493
- assert( actions != NULL );
1494
-
1495
- action_nw_addr = ( struct ofp_action_nw_addr * ) xcalloc( 1, sizeof( struct ofp_action_nw_addr ) );
1496
- action_nw_addr->type = type;
1497
- action_nw_addr->len = sizeof( struct ofp_action_nw_addr );
1498
- action_nw_addr->nw_addr = nw_addr;
1499
-
1500
- ret = append_to_tail( &actions->list, ( void * ) action_nw_addr );
1501
- if ( ret ) {
1502
- actions->n_actions++;
1503
- }
1504
-
1505
- return ret;
1506
- }
1507
-
1508
-
1509
- bool
1510
- append_action_set_nw_src( openflow_actions *actions, const uint32_t nw_addr ) {
1511
- char addr_str[ 16 ];
1512
- struct in_addr addr;
1513
-
1514
- addr.s_addr = htonl( nw_addr );
1515
- memset( addr_str, '\0', sizeof( addr_str ) );
1516
- inet_ntop( AF_INET, &addr, addr_str, sizeof( addr_str ) );
1517
- debug( "Appending a set nw_src action ( nw_addr = %s ).", addr_str );
1518
-
1519
- assert( actions != NULL );
1520
- return append_action_set_nw_addr( actions, OFPAT_SET_NW_SRC, nw_addr );
1521
- }
1522
-
1523
-
1524
- bool
1525
- append_action_set_nw_dst( openflow_actions *actions, const uint32_t nw_addr ) {
1526
- char addr_str[ 16 ];
1527
- struct in_addr addr;
1528
-
1529
- addr.s_addr = htonl( nw_addr );
1530
- memset( addr_str, '\0', sizeof( addr_str ) );
1531
- inet_ntop( AF_INET, &addr, addr_str, sizeof( addr_str ) );
1532
- debug( "Appending a set nw_dst action ( nw_addr = %s ).", addr_str );
1533
-
1534
- assert( actions != NULL );
1535
- return append_action_set_nw_addr( actions, OFPAT_SET_NW_DST, nw_addr );
1536
- }
1537
-
1538
-
1539
- bool
1540
- append_action_set_nw_tos( openflow_actions *actions, const uint8_t nw_tos ) {
1541
- bool ret;
1542
- struct ofp_action_nw_tos *action_nw_tos;
1543
-
1544
- debug( "Appending a set nw_tos action ( nw_tos = %#x ).", nw_tos );
1545
-
1546
- assert( actions != NULL );
1547
- assert( ( nw_tos & ~NW_TOS_MASK ) == 0 );
1548
-
1549
- action_nw_tos = ( struct ofp_action_nw_tos * ) xcalloc( 1, sizeof( struct ofp_action_nw_tos ) );
1550
- action_nw_tos->type = OFPAT_SET_NW_TOS;
1551
- action_nw_tos->len = sizeof( struct ofp_action_nw_tos );
1552
- action_nw_tos->nw_tos = nw_tos;
1553
-
1554
- ret = append_to_tail( &actions->list, ( void * ) action_nw_tos );
1555
- if ( ret ) {
1556
- actions->n_actions++;
1557
- }
1558
-
1559
- return ret;
1560
- }
1561
-
1562
-
1563
- static bool
1564
- append_action_set_tp_port( openflow_actions *actions, const uint16_t type, const uint16_t tp_port ) {
1565
- bool ret;
1566
- struct ofp_action_tp_port *action_tp_port;
1567
-
1568
- debug( "Appending a set tp_src/tp_dst action ( type = %#x, tp_port = %u ).", type, tp_port );
1569
-
1570
- assert( actions != NULL );
1571
-
1572
- action_tp_port = ( struct ofp_action_tp_port * ) xcalloc( 1, sizeof( struct ofp_action_tp_port ) );
1573
- action_tp_port->type = type;
1574
- action_tp_port->len = sizeof( struct ofp_action_tp_port );
1575
- action_tp_port->tp_port = tp_port;
1576
-
1577
- ret = append_to_tail( &actions->list, ( void * ) action_tp_port );
1578
- if ( ret ) {
1579
- actions->n_actions++;
1580
- }
1581
-
1582
- return ret;
1583
- }
1584
-
1585
-
1586
- bool
1587
- append_action_set_tp_src( openflow_actions *actions, const uint16_t tp_port ) {
1588
- debug( "Appending a set tp_src action ( tp_port = %u ).", tp_port );
1589
-
1590
- assert( actions != NULL );
1591
- return append_action_set_tp_port( actions, OFPAT_SET_TP_SRC, tp_port );
1592
- }
1593
-
1594
-
1595
- bool
1596
- append_action_set_tp_dst( openflow_actions *actions, const uint16_t tp_port ) {
1597
- debug( "Appending a set tp_dst action ( tp_port = %u ).", tp_port );
1598
-
1599
- assert( actions != NULL );
1600
- return append_action_set_tp_port( actions, OFPAT_SET_TP_DST, tp_port );
1601
- }
1602
-
1603
-
1604
- bool
1605
- append_action_enqueue( openflow_actions *actions, const uint16_t port, const uint32_t queue_id ) {
1606
- bool ret;
1607
- struct ofp_action_enqueue *action_enqueue;
1608
-
1609
- debug( "Appending an enqueue action ( port = %u, queue_id = %u ).", port, queue_id );
1610
-
1611
- assert( actions != NULL );
1612
-
1613
- action_enqueue = ( struct ofp_action_enqueue * ) xcalloc( 1, sizeof( struct ofp_action_enqueue ) );
1614
- action_enqueue->type = OFPAT_ENQUEUE;
1615
- action_enqueue->len = sizeof( struct ofp_action_enqueue );
1616
- action_enqueue->port = port;
1617
- action_enqueue->queue_id = queue_id;
1618
-
1619
- ret = append_to_tail( &actions->list, ( void * ) action_enqueue );
1620
- if ( ret ) {
1621
- actions->n_actions++;
1622
- }
1623
-
1624
- return ret;
1625
- }
1626
-
1627
-
1628
- bool
1629
- append_action_vendor( openflow_actions *actions, const uint32_t vendor, const buffer *body ) {
1630
- bool ret;
1631
- uint16_t body_length = 0;
1632
- struct ofp_action_vendor_header *action_vendor;
1633
-
1634
- if ( ( body != NULL ) && ( body->length > 0 ) ) {
1635
- body_length = ( uint16_t ) body->length;
1636
- }
1637
-
1638
- debug( "Appending a vendor action ( vendor = %#" PRIx32 ", body length = %u ).", vendor, body_length );
1639
-
1640
- assert( actions != NULL );
1641
- assert( ( body_length % 8 ) == 0 );
1642
-
1643
- action_vendor = ( struct ofp_action_vendor_header * )
1644
- xcalloc( 1, sizeof( struct ofp_action_vendor_header ) + body_length );
1645
- action_vendor->type = OFPAT_VENDOR;
1646
- action_vendor->len = ( uint16_t ) ( sizeof( struct ofp_action_vendor_header ) + body_length );
1647
- action_vendor->vendor = vendor;
1648
-
1649
- if ( body_length > 0 ) {
1650
- memcpy( ( char * ) action_vendor + sizeof( struct ofp_action_vendor_header ), body->data, body_length );
1651
- }
1652
-
1653
- ret = append_to_tail( &actions->list, ( void * ) action_vendor );
1654
- if ( ret ) {
1655
- actions->n_actions++;
1656
- }
1657
-
1658
- return ret;
1659
- }
1660
-
1661
- // A valid remote version is one of the defined wire protocol numbers for a
1662
- // HELLO message and strictly OpenFlow 1.0 for any other message.
1663
- bool
1664
- valid_message_version( const uint8_t type, const uint8_t version ) {
1665
- return type != OFPT_HELLO ? version == OFP_VERSION :
1666
- version >= OFP_VERSION && version <= 0x04; // 1.0~1.3
1667
- }
1668
-
1669
- static int
1670
- validate_header( const buffer *message, const uint8_t type,
1671
- const uint16_t min_length, const uint16_t max_length ) {
1672
- struct ofp_header *header;
1673
-
1674
- assert( message != NULL );
1675
- if ( message->length < sizeof( struct ofp_header ) ) {
1676
- return ERROR_TOO_SHORT_MESSAGE;
1677
- }
1678
-
1679
- header = ( struct ofp_header * ) message->data;
1680
- if ( ! valid_message_version( type, header->version ) ) {
1681
- return ERROR_UNSUPPORTED_VERSION;
1682
- }
1683
- if ( header->type > OFPT_QUEUE_GET_CONFIG_REPLY ) {
1684
- return ERROR_UNDEFINED_TYPE;
1685
- }
1686
- if ( header->type != type ) {
1687
- return ERROR_INVALID_TYPE;
1688
- }
1689
- if ( ntohs( header->length ) > max_length ) {
1690
- return ERROR_TOO_LONG_MESSAGE;
1691
- }
1692
- else if ( ntohs( header->length ) < min_length ) {
1693
- return ERROR_TOO_SHORT_MESSAGE;
1694
- }
1695
- if ( ntohs( header->length ) < message->length ) {
1696
- return ERROR_TOO_LONG_MESSAGE;
1697
- }
1698
- else if ( ntohs( header->length ) > message->length ) {
1699
- return ERROR_TOO_SHORT_MESSAGE;
1700
- }
1701
-
1702
- if ( message->length > max_length ) {
1703
- return ERROR_TOO_LONG_MESSAGE;
1704
- }
1705
-
1706
- return 0;
1707
- }
1708
-
1709
-
1710
- int
1711
- validate_hello( const buffer *message ) {
1712
- assert( message != NULL );
1713
- return validate_header( message, OFPT_HELLO, sizeof( struct ofp_header ), sizeof( struct ofp_header ) );
1714
- }
1715
-
1716
-
1717
- int
1718
- validate_error( const buffer *message ) {
1719
- int ret;
1720
- struct ofp_error_msg *error_msg;
1721
- const unsigned max_valid_code[OFPET_QUEUE_OP_FAILED + 1] = {
1722
- [ OFPET_HELLO_FAILED ] = OFPHFC_EPERM,
1723
- [ OFPET_BAD_REQUEST ] = OFPBRC_BUFFER_UNKNOWN,
1724
- [ OFPET_BAD_ACTION ] = OFPBAC_BAD_QUEUE,
1725
- [ OFPET_FLOW_MOD_FAILED ] = OFPFMFC_UNSUPPORTED,
1726
- [ OFPET_PORT_MOD_FAILED ] = OFPPMFC_BAD_HW_ADDR,
1727
- [ OFPET_QUEUE_OP_FAILED ] = OFPQOFC_EPERM,
1728
- };
1729
-
1730
- assert( message != NULL );
1731
-
1732
- ret = validate_header( message, OFPT_ERROR, sizeof( struct ofp_error_msg ), UINT16_MAX );
1733
- if ( ret < 0 ) {
1734
- return ret;
1735
- }
1736
-
1737
- error_msg = ( struct ofp_error_msg * ) message->data;
1738
- if ( ntohs( error_msg->type ) > OFPET_QUEUE_OP_FAILED ) {
1739
- return ERROR_INVALID_ERROR_TYPE;
1740
- }
1741
- if ( ntohs( error_msg->code ) > max_valid_code[ ntohs( error_msg->type ) ] ) {
1742
- return ERROR_INVALID_ERROR_CODE;
1743
- }
1744
-
1745
- return 0;
1746
- }
1747
-
1748
-
1749
- int
1750
- validate_echo_request( const buffer *message ) {
1751
- int ret;
1752
- struct ofp_header *header;
1753
-
1754
- assert( message != NULL );
1755
-
1756
- ret = validate_header( message, OFPT_ECHO_REQUEST, sizeof( struct ofp_header ), UINT16_MAX );
1757
- if ( ret < 0 ) {
1758
- return ret;
1759
- }
1760
-
1761
- header = ( struct ofp_header * ) message->data;
1762
- if ( message->length != ntohs( header->length ) ) {
1763
- return ERROR_INVALID_LENGTH;
1764
- }
1765
-
1766
- return 0;
1767
- }
1768
-
1769
-
1770
- int
1771
- validate_echo_reply( const buffer *message ) {
1772
- int ret;
1773
- struct ofp_header *header;
1774
-
1775
- assert( message != NULL );
1776
-
1777
- ret = validate_header( message, OFPT_ECHO_REPLY, sizeof( struct ofp_header ), UINT16_MAX );
1778
- if ( ret < 0 ) {
1779
- return ret;
1780
- }
1781
-
1782
- header = ( struct ofp_header * ) message->data;
1783
- if ( message->length != ntohs( header->length ) ) {
1784
- return ERROR_INVALID_LENGTH;
1785
- }
1786
-
1787
- return 0;
1788
- }
1789
-
1790
-
1791
- int
1792
- validate_vendor( const buffer *message ) {
1793
- int ret;
1794
- struct ofp_vendor_header *vendor_header;
1795
-
1796
- assert( message != NULL );
1797
-
1798
- ret = validate_header( message, OFPT_VENDOR, sizeof( struct ofp_vendor_header ), UINT16_MAX );
1799
- if ( ret < 0 ) {
1800
- return ret;
1801
- }
1802
-
1803
- vendor_header = ( struct ofp_vendor_header * ) message->data;
1804
- if ( message->length != ntohs( vendor_header->header.length ) ) {
1805
- return ERROR_INVALID_LENGTH;
1806
- }
1807
-
1808
- return 0;
1809
- }
1810
-
1811
-
1812
- int
1813
- validate_features_request( const buffer *message ) {
1814
- assert( message != NULL );
1815
- return validate_header( message, OFPT_FEATURES_REQUEST, sizeof( struct ofp_header ),
1816
- sizeof( struct ofp_header ) );
1817
- }
1818
-
1819
-
1820
- static int
1821
- validate_phy_port_no( const uint16_t port_no ) {
1822
- if ( port_no == OFPP_LOCAL ) {
1823
- return 0;
1824
- }
1825
- if ( ( port_no == 0 ) || ( port_no > OFPP_MAX ) ) {
1826
- return ERROR_INVALID_PORT_NO;
1827
- }
1828
-
1829
- return 0;
1830
- }
1831
-
1832
-
1833
- static int
1834
- validate_in_port_no( const uint16_t port_no ) {
1835
- if ( ( port_no == OFPP_CONTROLLER ) || ( port_no == OFPP_NONE ) ) {
1836
- return 0;
1837
- }
1838
-
1839
- return validate_phy_port_no( port_no );
1840
- }
1841
-
1842
-
1843
- static int
1844
- validate_out_port_no( const uint16_t port_no ) {
1845
- if ( port_no >= OFPP_IN_PORT ) {
1846
- return 0;
1847
- }
1848
-
1849
- return validate_phy_port_no( port_no );
1850
- }
1851
-
1852
-
1853
- static int
1854
- validate_phy_port( struct ofp_phy_port *port ) {
1855
- int ret;
1856
- struct ofp_phy_port port_h;
1857
-
1858
- assert( port != NULL );
1859
-
1860
- ntoh_phy_port( &port_h, port );
1861
-
1862
- ret = validate_phy_port_no( port_h.port_no );
1863
- if ( ret < 0 ) {
1864
- return ret;
1865
- }
1866
-
1867
- if ( ( port_h.config & ( uint32_t ) ~PORT_CONFIG ) != 0 ) {
1868
- return ERROR_INVALID_PORT_CONFIG;
1869
- }
1870
- if ( ( port_h.state & ( uint32_t ) ~PORT_STATE ) != 0 ) {
1871
- return ERROR_INVALID_PORT_STATE;
1872
- }
1873
- if ( ( port_h.curr & ( uint32_t ) ~PORT_FEATURES ) != 0
1874
- || ( port_h.advertised & ( uint32_t ) ~PORT_FEATURES ) != 0
1875
- || ( port_h.supported & ( uint32_t ) ~PORT_FEATURES ) != 0
1876
- || ( port_h.peer & ( uint32_t ) ~PORT_FEATURES ) != 0 ) {
1877
- return ERROR_INVALID_PORT_FEATURES;
1878
- }
1879
-
1880
- return 0;
1881
- }
1882
-
1883
-
1884
- static int
1885
- validate_phy_ports( struct ofp_phy_port *ports, const int n_ports ) {
1886
- int i;
1887
- int ret;
1888
- struct ofp_phy_port *port;
1889
-
1890
- assert( ports != NULL );
1891
- assert( n_ports );
1892
-
1893
- port = ports;
1894
- for ( i = 0; i < n_ports; i++ ) {
1895
- ret = validate_phy_port( port );
1896
- if ( ret < 0 ) {
1897
- return ret;
1898
- }
1899
- port++;
1900
- }
1901
-
1902
- return 0;
1903
- }
1904
-
1905
-
1906
- int
1907
- validate_features_reply( const buffer *message ) {
1908
- void *p;
1909
- int ret;
1910
- int n_ports;
1911
- uint16_t port_length;
1912
- struct ofp_switch_features *switch_features;
1913
-
1914
- assert( message != NULL );
1915
-
1916
- ret = validate_header( message, OFPT_FEATURES_REPLY, sizeof( struct ofp_switch_features ), UINT16_MAX );
1917
- if ( ret < 0 ) {
1918
- return ret;
1919
- }
1920
-
1921
- switch_features = ( struct ofp_switch_features * ) message->data;
1922
-
1923
- // switch_features->datapath_id
1924
- // switch_features->n_buffers
1925
-
1926
- if ( switch_features->n_tables == 0 ) {
1927
- return ERROR_NO_TABLE_AVAILABLE;
1928
- }
1929
-
1930
- port_length = ( uint16_t ) ( ntohs( switch_features->header.length )
1931
- - sizeof( struct ofp_switch_features ) );
1932
- if ( port_length % sizeof( struct ofp_phy_port ) != 0 ) {
1933
- return ERROR_INVALID_LENGTH;
1934
- }
1935
-
1936
- if ( port_length > 0 ) {
1937
- p = ( void * ) ( ( char * ) message->data + offsetof( struct ofp_switch_features, ports ) );
1938
- n_ports = port_length / sizeof( struct ofp_phy_port );
1939
-
1940
- ret = validate_phy_ports( p, n_ports );
1941
- if ( ret < 0 ) {
1942
- return ret;
1943
- }
1944
- }
1945
-
1946
- return 0;
1947
- }
1948
-
1949
-
1950
- int
1951
- validate_get_config_request( const buffer *message ) {
1952
- assert( message != NULL );
1953
- return validate_header( message, OFPT_GET_CONFIG_REQUEST, sizeof( struct ofp_header ),
1954
- sizeof( struct ofp_header ) );
1955
- }
1956
-
1957
-
1958
- static int
1959
- validate_switch_config( const buffer *message, const uint8_t type ) {
1960
- int ret;
1961
- struct ofp_switch_config *switch_config;
1962
-
1963
- assert( message != NULL );
1964
- assert( ( type == OFPT_GET_CONFIG_REPLY ) || ( type == OFPT_SET_CONFIG ) );
1965
-
1966
- ret = validate_header( message, type, sizeof( struct ofp_switch_config ),
1967
- sizeof( struct ofp_switch_config ) );
1968
- if ( ret < 0 ) {
1969
- return ret;
1970
- }
1971
-
1972
- switch_config = ( struct ofp_switch_config * ) message->data;
1973
- if ( ntohs( switch_config->flags ) > OFPC_FRAG_MASK ) {
1974
- return ERROR_INVALID_SWITCH_CONFIG;
1975
- }
1976
-
1977
- // switch_config->miss_send_len
1978
-
1979
- return 0;
1980
- }
1981
-
1982
-
1983
- int
1984
- validate_get_config_reply( const buffer *message ) {
1985
- assert( message != NULL );
1986
- return validate_switch_config( message, OFPT_GET_CONFIG_REPLY );
1987
- }
1988
-
1989
-
1990
- int
1991
- validate_set_config( const buffer *message ) {
1992
- assert( message != NULL );
1993
- return validate_switch_config( message, OFPT_SET_CONFIG );
1994
- }
1995
-
1996
-
1997
- int
1998
- validate_packet_in( const buffer *message ) {
1999
- int ret;
2000
- uint16_t data_length;
2001
- struct ofp_packet_in *packet_in;
2002
-
2003
- assert( message != NULL );
2004
-
2005
- ret = validate_header( message, OFPT_PACKET_IN, offsetof( struct ofp_packet_in, data ), UINT16_MAX );
2006
- if ( ret < 0 ) {
2007
- return ret;
2008
- }
2009
-
2010
- packet_in = ( struct ofp_packet_in * ) message->data;
2011
-
2012
- // packet_in->buffer_id
2013
- // packet_in->total_len
2014
- // packet_in->in_port
2015
-
2016
- ret = validate_in_port_no( ntohs( packet_in->in_port ) );
2017
- if ( ret < 0 ) {
2018
- return ret;
2019
- }
2020
-
2021
- if ( packet_in->reason > OFPR_ACTION ) {
2022
- return ERROR_INVALID_PACKET_IN_REASON;
2023
- }
2024
-
2025
- data_length = ( uint16_t ) ( ntohs( packet_in->header.length ) - offsetof( struct ofp_packet_in, data ) );
2026
- if ( data_length > 0 ) {
2027
- // FIXME: it may be better to check if this is a valid Ethernet frame or not.
2028
- }
2029
-
2030
- return 0;
2031
- }
2032
-
2033
-
2034
- static int
2035
- validate_wildcards( const uint32_t wildcards ) {
2036
- if ( ( wildcards & ( uint32_t ) ~OFPFW_ALL ) != 0 ) {
2037
- return ERROR_INVALID_WILDCARDS;
2038
- }
2039
-
2040
- return 0;
2041
- }
2042
-
2043
-
2044
- static int
2045
- validate_vlan_vid( const uint16_t vid ) {
2046
- if ( ( vid != UINT16_MAX ) && ( ( vid & ~VLAN_VID_MASK ) != 0 ) ) {
2047
- return ERROR_INVALID_VLAN_VID;
2048
- }
2049
-
2050
- return 0;
2051
- }
2052
-
2053
-
2054
- static int
2055
- validate_vlan_pcp( const uint8_t pcp ) {
2056
- if ( ( pcp & ~VLAN_PCP_MASK ) != 0 ) {
2057
- return ERROR_INVALID_VLAN_PCP;
2058
- }
2059
-
2060
- return 0;
2061
- }
2062
-
2063
-
2064
- static int
2065
- validate_nw_tos( const uint8_t tos ) {
2066
- if ( ( tos & ~NW_TOS_MASK ) != 0 ) {
2067
- return ERROR_INVALID_NW_TOS;
2068
- }
2069
-
2070
- return 0;
2071
- }
2072
-
2073
-
2074
- static int
2075
- validate_match( const struct ofp_match match ) {
2076
- int ret;
2077
-
2078
- ret = validate_wildcards( match.wildcards );
2079
- if ( ret < 0 ) {
2080
- return ret;
2081
- }
2082
-
2083
- ret = validate_vlan_vid( match.dl_vlan );
2084
- if ( ret < 0 ) {
2085
- return ret;
2086
- }
2087
-
2088
- ret = validate_vlan_pcp( match.dl_vlan_pcp );
2089
- if ( ret < 0 ) {
2090
- return ret;
2091
- }
2092
-
2093
- ret = validate_nw_tos( match.nw_tos );
2094
- if ( ret < 0 ) {
2095
- return ret;
2096
- }
2097
-
2098
- return 0;
2099
- }
2100
-
2101
-
2102
- int
2103
- validate_flow_removed( const buffer *message ) {
2104
- int ret;
2105
- struct ofp_match match;
2106
- struct ofp_flow_removed *flow_removed;
2107
-
2108
- assert( message != NULL );
2109
-
2110
- ret = validate_header( message, OFPT_FLOW_REMOVED, sizeof( struct ofp_flow_removed ),
2111
- sizeof( struct ofp_flow_removed ) );
2112
- if ( ret < 0 ) {
2113
- return ret;
2114
- }
2115
-
2116
- flow_removed = ( struct ofp_flow_removed * ) message->data;
2117
-
2118
- ntoh_match( &match, &flow_removed->match );
2119
-
2120
- ret = validate_match( match );
2121
- if ( ret < 0 ) {
2122
- return ret;
2123
- }
2124
-
2125
- // flow_removed->cookie
2126
-
2127
- if ( ( ( match.wildcards & OFPFW_ALL ) == 0 ) && ( ntohs( flow_removed->priority ) != UINT16_MAX ) ) {
2128
- return ERROR_INVALID_FLOW_PRIORITY;
2129
- }
2130
-
2131
- if ( flow_removed->reason > OFPRR_DELETE ) {
2132
- return ERROR_INVALID_FLOW_REMOVED_REASON;
2133
- }
2134
-
2135
- // flow_removed->duration_sec
2136
- // flow_removed->duration_nsec
2137
- // flow_removed->idle_timeout
2138
- // flow_removed->packet_count
2139
- // flow_removed->byte_count
2140
-
2141
- return 0;
2142
- }
2143
-
2144
-
2145
- int
2146
- validate_port_status( const buffer *message ) {
2147
- int ret;
2148
- struct ofp_port_status *port_status;
2149
-
2150
- assert( message != NULL );
2151
-
2152
- ret = validate_header( message, OFPT_PORT_STATUS, sizeof( struct ofp_port_status ),
2153
- sizeof( struct ofp_port_status ) );
2154
- if ( ret < 0 ) {
2155
- return ret;
2156
- }
2157
-
2158
- port_status = ( struct ofp_port_status * ) message->data;
2159
- if ( port_status->reason > OFPPR_MODIFY ) {
2160
- return ERROR_INVALID_PORT_STATUS_REASON;
2161
- }
2162
-
2163
- ret = validate_phy_port( &port_status->desc );
2164
- if ( ret < 0 ) {
2165
- return ret;
2166
- }
2167
-
2168
- return 0;
2169
- }
2170
-
2171
-
2172
- int
2173
- validate_packet_out( const buffer *message ) {
2174
- int ret;
2175
- uint16_t data_length;
2176
- struct ofp_packet_out *packet_out;
2177
-
2178
- assert( message != NULL );
2179
-
2180
- ret = validate_header( message, OFPT_PACKET_OUT, offsetof( struct ofp_packet_out, actions ),
2181
- UINT16_MAX );
2182
- if ( ret < 0 ) {
2183
- return ret;
2184
- }
2185
-
2186
- packet_out = ( struct ofp_packet_out * ) message->data;
2187
-
2188
- ret = validate_in_port_no( ntohs( packet_out->in_port ) );
2189
- if ( ret < 0 ) {
2190
- return ret;
2191
- }
2192
-
2193
- if ( ntohs( packet_out->actions_len ) > 0 ) {
2194
- ret = validate_actions( packet_out->actions, ntohs( packet_out->actions_len ) );
2195
- if ( ret < 0 ) {
2196
- return ret;
2197
- }
2198
- }
2199
-
2200
- data_length = ( uint16_t ) ( ntohs( packet_out->header.length )
2201
- - offsetof( struct ofp_packet_out, actions )
2202
- - ntohs( packet_out->actions_len ) );
2203
-
2204
- if ( data_length > 0 ) {
2205
- // FIXME: it may be better to check if this is a valid Ethernet frame or not.
2206
- }
2207
-
2208
- return 0;
2209
- }
2210
-
2211
-
2212
- int
2213
- validate_flow_mod( const buffer *message ) {
2214
- int ret;
2215
- uint16_t actions_length;
2216
- struct ofp_match match;
2217
- struct ofp_flow_mod *flow_mod;
2218
-
2219
- assert( message != NULL );
2220
-
2221
- ret = validate_header( message, OFPT_FLOW_MOD, offsetof( struct ofp_flow_mod, actions ),
2222
- UINT16_MAX );
2223
- if ( ret < 0 ) {
2224
- return ret;
2225
- }
2226
-
2227
- flow_mod = ( struct ofp_flow_mod * ) message->data;
2228
-
2229
- ntoh_match( &match, &flow_mod->match );
2230
-
2231
- ret = validate_match( match );
2232
- if ( ret < 0 ) {
2233
- return ret;
2234
- }
2235
-
2236
- // flow_mod->cookie
2237
-
2238
- if ( ntohs( flow_mod->command ) > OFPFC_DELETE_STRICT ) {
2239
- return ERROR_UNDEFINED_FLOW_MOD_COMMAND;
2240
- }
2241
-
2242
- // flow_mod->idle_timeout
2243
- // flow_mod->hard_timeout
2244
-
2245
- if ( ( ( match.wildcards & OFPFW_ALL ) == 0 ) && ( ntohs( flow_mod->priority ) != UINT16_MAX ) ) {
2246
- return ERROR_INVALID_FLOW_PRIORITY;
2247
- }
2248
-
2249
- // flow_mod->buffer_id
2250
-
2251
- if ( ( ntohs( flow_mod->command ) == OFPFC_DELETE )
2252
- || ( ntohs( flow_mod->command ) == OFPFC_DELETE_STRICT ) ) {
2253
- ret = validate_out_port_no( ntohs( flow_mod->out_port ) );
2254
- if ( ret < 0 ) {
2255
- return ret;
2256
- }
2257
- }
2258
-
2259
- if ( ( ntohs( flow_mod->flags ) & ~FLOW_MOD_FLAGS ) != 0 ) {
2260
- return ERROR_INVALID_FLOW_MOD_FLAGS;
2261
- }
2262
-
2263
- actions_length = ( uint16_t ) ( ntohs( flow_mod->header.length )
2264
- - offsetof( struct ofp_flow_mod, actions ) );
2265
-
2266
- if ( actions_length > 0 ) {
2267
- ret = validate_actions( flow_mod->actions, actions_length );
2268
- if ( ret < 0 ) {
2269
- return ret;
2270
- }
2271
-
2272
- }
2273
-
2274
- return 0;
2275
- }
2276
-
2277
-
2278
- int
2279
- validate_port_mod( const buffer *message ) {
2280
- int ret;
2281
- struct ofp_port_mod *port_mod;
2282
-
2283
- assert( message != NULL );
2284
-
2285
- ret = validate_header( message, OFPT_PORT_MOD, sizeof( struct ofp_port_mod ),
2286
- sizeof( struct ofp_port_mod ) );
2287
- if ( ret < 0 ) {
2288
- return ret;
2289
- }
2290
-
2291
- port_mod = ( struct ofp_port_mod * ) message->data;
2292
-
2293
- ret = validate_phy_port_no( ntohs( port_mod->port_no ) );
2294
- if ( ret < 0 ) {
2295
- return ret;
2296
- }
2297
- if ( ( ntohs( port_mod->port_no ) > OFPP_MAX ) && ( ntohs( port_mod->port_no ) != OFPP_LOCAL ) ) {
2298
- return ERROR_INVALID_PORT_NO;
2299
- }
2300
-
2301
- // port_mod->hw_addr
2302
-
2303
- if ( ( ntohl( port_mod->config ) & ( uint32_t ) ~PORT_CONFIG ) != 0 ) {
2304
- return ERROR_INVALID_PORT_CONFIG;
2305
- }
2306
- if ( ( ntohl( port_mod->mask ) & ( uint32_t ) ~PORT_CONFIG ) != 0 ) {
2307
- return ERROR_INVALID_PORT_MASK;
2308
- }
2309
- if ( ( ntohl( port_mod->advertise ) & ( uint32_t ) ~PORT_FEATURES ) != 0 ) {
2310
- return ERROR_INVALID_PORT_FEATURES;
2311
- }
2312
-
2313
- return 0;
2314
- }
2315
-
2316
-
2317
- int
2318
- validate_desc_stats_request( const buffer *message ) {
2319
- int ret;
2320
- struct ofp_stats_request *stats_request;
2321
-
2322
- assert( message != NULL );
2323
-
2324
- ret = validate_header( message, OFPT_STATS_REQUEST, sizeof( struct ofp_stats_request ),
2325
- sizeof( struct ofp_stats_request ) );
2326
- if ( ret < 0 ) {
2327
- return ret;
2328
- }
2329
-
2330
- stats_request = ( struct ofp_stats_request * ) message->data;
2331
-
2332
- if ( ntohs( stats_request->type ) != OFPST_DESC ) {
2333
- return ERROR_INVALID_STATS_TYPE;
2334
- }
2335
- if ( ntohs( stats_request->flags ) != 0 ) {
2336
- return ERROR_INVALID_STATS_REQUEST_FLAGS;
2337
- }
2338
-
2339
- return 0;
2340
- }
2341
-
2342
-
2343
- int
2344
- validate_flow_stats_request( const buffer *message ) {
2345
- int ret;
2346
- struct ofp_match match;
2347
- struct ofp_stats_request *stats_request;
2348
- struct ofp_flow_stats_request *flow_stats_request;
2349
-
2350
- assert( message != NULL );
2351
-
2352
- ret = validate_header( message, OFPT_STATS_REQUEST,
2353
- offsetof( struct ofp_stats_request, body )
2354
- + sizeof( struct ofp_flow_stats_request ),
2355
- offsetof( struct ofp_stats_request, body )
2356
- + sizeof( struct ofp_flow_stats_request ) );
2357
- if ( ret < 0 ) {
2358
- return ret;
2359
- }
2360
-
2361
- stats_request = ( struct ofp_stats_request * ) message->data;
2362
-
2363
- if ( ntohs( stats_request->type ) != OFPST_FLOW ) {
2364
- return ERROR_INVALID_STATS_TYPE;
2365
- }
2366
-
2367
- if ( ntohs( stats_request->flags ) != 0 ) {
2368
- return ERROR_INVALID_STATS_REQUEST_FLAGS;
2369
- }
2370
-
2371
- flow_stats_request = ( struct ofp_flow_stats_request * ) stats_request->body;
2372
- ntoh_match( &match, &flow_stats_request->match );
2373
-
2374
- ret = validate_match( match );
2375
- if ( ret < 0 ) {
2376
- return ret;
2377
- }
2378
-
2379
- // flow_stats_request->table_id
2380
-
2381
- ret = validate_out_port_no( ntohs( flow_stats_request->out_port ) );
2382
- if ( ret < 0 ) {
2383
- return ret;
2384
- }
2385
-
2386
- return 0;
2387
- }
2388
-
2389
-
2390
- int
2391
- validate_aggregate_stats_request( const buffer *message ) {
2392
- int ret;
2393
- struct ofp_match match;
2394
- struct ofp_stats_request *stats_request;
2395
- struct ofp_aggregate_stats_request *aggregate_stats_request;
2396
-
2397
- assert( message != NULL );
2398
-
2399
- ret = validate_header( message, OFPT_STATS_REQUEST,
2400
- offsetof( struct ofp_stats_request, body )
2401
- + sizeof( struct ofp_aggregate_stats_request ),
2402
- offsetof( struct ofp_stats_request, body )
2403
- + sizeof( struct ofp_aggregate_stats_request ) );
2404
- if ( ret < 0 ) {
2405
- return ret;
2406
- }
2407
-
2408
- stats_request = ( struct ofp_stats_request * ) message->data;
2409
-
2410
- if ( ntohs( stats_request->type ) != OFPST_AGGREGATE ) {
2411
- return ERROR_INVALID_STATS_TYPE;
2412
- }
2413
- if ( ntohs( stats_request->flags ) != 0 ) {
2414
- return ERROR_INVALID_STATS_REQUEST_FLAGS;
2415
- }
2416
-
2417
- aggregate_stats_request = ( struct ofp_aggregate_stats_request * ) stats_request->body;
2418
- ntoh_match( &match, &aggregate_stats_request->match );
2419
-
2420
- ret = validate_match( match );
2421
- if ( ret < 0 ) {
2422
- return ret;
2423
- }
2424
-
2425
- // aggregate_stats_request->table_id
2426
-
2427
- ret = validate_out_port_no( ntohs( aggregate_stats_request->out_port ) );
2428
- if ( ret < 0 ) {
2429
- return ret;
2430
- }
2431
-
2432
- return 0;
2433
- }
2434
-
2435
-
2436
- int
2437
- validate_table_stats_request( const buffer *message ) {
2438
- int ret;
2439
- struct ofp_stats_request *stats_request;
2440
-
2441
- assert( message != NULL );
2442
-
2443
- ret = validate_header( message, OFPT_STATS_REQUEST, offsetof( struct ofp_stats_request, body ),
2444
- offsetof( struct ofp_stats_request, body ) );
2445
- if ( ret < 0 ) {
2446
- return ret;
2447
- }
2448
-
2449
- stats_request = ( struct ofp_stats_request * ) message->data;
2450
-
2451
- if ( ntohs( stats_request->type ) != OFPST_TABLE ) {
2452
- return ERROR_INVALID_STATS_TYPE;
2453
- }
2454
- if ( ntohs( stats_request->flags ) != 0 ) {
2455
- return ERROR_INVALID_STATS_REQUEST_FLAGS;
2456
- }
2457
-
2458
- return 0;
2459
- }
2460
-
2461
-
2462
- int
2463
- validate_port_stats_request( const buffer *message ) {
2464
- int ret;
2465
- struct ofp_stats_request *stats_request;
2466
- struct ofp_port_stats_request *port_stats_request;
2467
-
2468
- assert( message != NULL );
2469
-
2470
- ret = validate_header( message, OFPT_STATS_REQUEST,
2471
- offsetof( struct ofp_stats_request, body )
2472
- + sizeof( struct ofp_port_stats_request ),
2473
- offsetof( struct ofp_stats_request, body )
2474
- + sizeof( struct ofp_port_stats_request ) );
2475
- if ( ret < 0 ) {
2476
- return ret;
2477
- }
2478
-
2479
- stats_request = ( struct ofp_stats_request * ) message->data;
2480
-
2481
- if ( ntohs( stats_request->type ) != OFPST_PORT ) {
2482
- return ERROR_INVALID_STATS_TYPE;
2483
- }
2484
- if ( ntohs( stats_request->flags ) != 0 ) {
2485
- return ERROR_INVALID_STATS_REQUEST_FLAGS;
2486
- }
2487
-
2488
- port_stats_request = ( struct ofp_port_stats_request * ) stats_request->body;
2489
-
2490
- if ( ntohs( port_stats_request->port_no ) > OFPP_MAX
2491
- && ntohs( port_stats_request->port_no ) != OFPP_NONE
2492
- && ntohs( port_stats_request->port_no ) != OFPP_LOCAL ) {
2493
- return ERROR_INVALID_PORT_NO;
2494
- }
2495
-
2496
- return 0;
2497
- }
2498
-
2499
-
2500
- int
2501
- validate_queue_stats_request( const buffer *message ) {
2502
- int ret;
2503
- struct ofp_stats_request *stats_request;
2504
- struct ofp_queue_stats_request *queue_stats_request;
2505
-
2506
- assert( message != NULL );
2507
-
2508
- ret = validate_header( message, OFPT_STATS_REQUEST,
2509
- offsetof( struct ofp_stats_request, body )
2510
- + sizeof( struct ofp_queue_stats_request ),
2511
- offsetof( struct ofp_stats_request, body )
2512
- + sizeof( struct ofp_queue_stats_request ) );
2513
- if ( ret < 0 ) {
2514
- return ret;
2515
- }
2516
-
2517
- stats_request = ( struct ofp_stats_request * ) message->data;
2518
-
2519
- if ( ntohs( stats_request->type ) != OFPST_QUEUE ) {
2520
- return ERROR_INVALID_STATS_TYPE;
2521
- }
2522
- if ( ntohs( stats_request->flags ) != 0 ) {
2523
- return ERROR_INVALID_STATS_REQUEST_FLAGS;
2524
- }
2525
-
2526
- queue_stats_request = ( struct ofp_queue_stats_request * ) stats_request->body;
2527
-
2528
- ret = validate_phy_port_no( ntohs( queue_stats_request->port_no ) );
2529
- if ( ret < 0 ) {
2530
- return ret;
2531
- }
2532
-
2533
- // queue_stats_request->queue_id
2534
- return 0;
2535
- }
2536
-
2537
-
2538
- int
2539
- validate_vendor_stats_request( const buffer *message ) {
2540
- int ret;
2541
- struct ofp_stats_request *stats_request;
2542
-
2543
- assert( message != NULL );
2544
-
2545
- ret = validate_header( message, OFPT_STATS_REQUEST,
2546
- offsetof( struct ofp_stats_request, body ) + sizeof( uint32_t ),
2547
- UINT16_MAX );
2548
- if ( ret < 0 ) {
2549
- return ret;
2550
- }
2551
-
2552
- stats_request = ( struct ofp_stats_request * ) message->data;
2553
-
2554
- if ( ntohs( stats_request->type ) != OFPST_VENDOR ) {
2555
- return ERROR_INVALID_STATS_TYPE;
2556
- }
2557
- if ( ntohs( stats_request->flags ) != 0 ) {
2558
- return ERROR_INVALID_STATS_REQUEST_FLAGS;
2559
- }
2560
-
2561
- // vendor_id
2562
- return 0;
2563
- }
2564
-
2565
-
2566
- int
2567
- validate_stats_request( const buffer *message ) {
2568
- struct ofp_stats_request *request;
2569
-
2570
- assert( message != NULL );
2571
-
2572
- request = ( struct ofp_stats_request * ) message->data;
2573
-
2574
- // TODO: if ( request->header.type != OFPT_STATS_REQUEST ) { ... }
2575
-
2576
- switch ( ntohs( request->type ) ) {
2577
- case OFPST_DESC:
2578
- return validate_desc_stats_request( message );
2579
- case OFPST_FLOW:
2580
- return validate_flow_stats_request( message );
2581
- case OFPST_AGGREGATE:
2582
- return validate_aggregate_stats_request( message );
2583
- case OFPST_TABLE:
2584
- return validate_table_stats_request( message );
2585
- case OFPST_PORT:
2586
- return validate_port_stats_request( message );
2587
- case OFPST_QUEUE:
2588
- return validate_queue_stats_request( message );
2589
- case OFPST_VENDOR:
2590
- return validate_vendor_stats_request( message );
2591
- default:
2592
- break;
2593
- }
2594
-
2595
- return ERROR_UNSUPPORTED_STATS_TYPE;
2596
- }
2597
-
2598
-
2599
- int
2600
- validate_desc_stats_reply( const buffer *message ) {
2601
- int ret;
2602
- struct ofp_stats_reply *stats_reply;
2603
-
2604
- assert( message != NULL );
2605
-
2606
- ret = validate_header( message, OFPT_STATS_REPLY,
2607
- offsetof( struct ofp_stats_reply, body ),
2608
- offsetof( struct ofp_stats_reply, body ) + sizeof( struct ofp_desc_stats ) );
2609
- if ( ret < 0 ) {
2610
- return ret;
2611
- }
2612
-
2613
- stats_reply = ( struct ofp_stats_reply * ) message->data;
2614
- if ( ntohs( stats_reply->flags ) != 0 ) {
2615
- return ERROR_INVALID_STATS_REPLY_FLAGS;
2616
- }
2617
-
2618
- return 0;
2619
- }
2620
-
2621
-
2622
- int
2623
- validate_flow_stats_reply( const buffer *message ) {
2624
- int ret;
2625
- uint16_t offset;
2626
- uint16_t flow_length;
2627
- uint16_t actions_length;
2628
- struct ofp_stats_reply *stats_reply;
2629
- struct ofp_flow_stats *flow_stats;
2630
- struct ofp_action_header *actions_head;
2631
- struct ofp_match match;
2632
-
2633
- assert( message != NULL );
2634
-
2635
- ret = validate_header( message, OFPT_STATS_REPLY, offsetof( struct ofp_stats_reply, body ),
2636
- UINT16_MAX );
2637
- if ( ret < 0 ) {
2638
- return ret;
2639
- }
2640
-
2641
- stats_reply = ( struct ofp_stats_reply * ) message->data;
2642
- if ( ( ntohs( stats_reply->flags ) & ~OFPSF_REPLY_MORE ) != 0 ) {
2643
- return ERROR_INVALID_STATS_REPLY_FLAGS;
2644
- }
2645
-
2646
- flow_length = ( uint16_t ) ( ntohs( stats_reply->header.length )
2647
- - offsetof( struct ofp_stats_reply, body ) );
2648
- offset = offsetof( struct ofp_stats_reply, body );
2649
- flow_stats = ( struct ofp_flow_stats * ) ( ( char * ) message->data + offset );
2650
-
2651
- while ( flow_length > 0 ) {
2652
- // flow_stats->length
2653
- // flow_stats->table_id
2654
-
2655
- ntoh_match( &match, &flow_stats->match );
2656
-
2657
- ret = validate_match( match );
2658
- if ( ret < 0 ) {
2659
- return ret;
2660
- }
2661
-
2662
- // flow_stats->duration_sec
2663
- // flow_stats->duration_nsec
2664
-
2665
- if ( ( ( match.wildcards & OFPFW_ALL ) == 0 ) && ( ntohs( flow_stats->priority ) < UINT16_MAX ) ) {
2666
- return ERROR_INVALID_FLOW_PRIORITY;
2667
- }
2668
-
2669
- // flow_stats->idle_timeout
2670
- // flow_stats->hard_timeout
2671
- // flow_stats->cookie
2672
- // flow_stats->packet_count
2673
- // flow_stats->byte_count
2674
-
2675
- actions_length = ( uint16_t ) ( ntohs( flow_stats->length )
2676
- - offsetof( struct ofp_flow_stats, actions ) );
2677
-
2678
- if ( actions_length > 0 ) {
2679
- actions_head = ( struct ofp_action_header * ) ( ( char * ) flow_stats
2680
- + offsetof( struct ofp_flow_stats, actions ) );
2681
-
2682
- ret = validate_actions( actions_head, actions_length );
2683
- if ( ret < 0 ) {
2684
- return ret;
2685
- }
2686
- }
2687
-
2688
- flow_length = ( uint16_t ) ( flow_length - ntohs( flow_stats->length ) );
2689
- flow_stats = ( struct ofp_flow_stats * ) ( ( char * ) flow_stats + ntohs( flow_stats->length ) );
2690
- }
2691
-
2692
- return 0;
2693
- }
2694
-
2695
-
2696
- int
2697
- validate_aggregate_stats_reply( const buffer *message ) {
2698
- int ret;
2699
- struct ofp_stats_reply *stats_reply;
2700
-
2701
- assert( message != NULL );
2702
-
2703
- ret = validate_header( message, OFPT_STATS_REPLY,
2704
- offsetof( struct ofp_stats_reply, body ),
2705
- offsetof( struct ofp_stats_reply, body ) + sizeof( struct ofp_aggregate_stats_reply ) );
2706
- if ( ret < 0 ) {
2707
- return ret;
2708
- }
2709
-
2710
- stats_reply = ( struct ofp_stats_reply * ) message->data;
2711
- if ( ntohs( stats_reply->flags ) != 0 ) {
2712
- return ERROR_INVALID_STATS_REPLY_FLAGS;
2713
- }
2714
-
2715
- // uint16_t offset = offsetof( struct ofp_stats_reply, body );
2716
- // struct ofp_aggregate_stats_reply *aggregate_stats = ( struct ofp_aggregate_stats_reply * ) ( ( char * ) message->data + offset );
2717
-
2718
- // aggregate_stats->packet_count
2719
- // aggregate_stats->byte_count
2720
- // aggregate_stats->flow_count
2721
-
2722
- return 0;
2723
- }
2724
-
2725
-
2726
- int
2727
- validate_table_stats_reply( const buffer *message ) {
2728
- int i;
2729
- int ret;
2730
- uint16_t tables_length;
2731
- uint16_t n_tables;
2732
- uint16_t offset;
2733
- struct ofp_stats_reply *stats_reply;
2734
- struct ofp_table_stats *table_stats;
2735
-
2736
- assert( message != NULL );
2737
-
2738
- ret = validate_header( message, OFPT_STATS_REPLY,
2739
- offsetof( struct ofp_stats_reply, body ),
2740
- UINT16_MAX );
2741
- if ( ret < 0 ) {
2742
- return ret;
2743
- }
2744
-
2745
- stats_reply = ( struct ofp_stats_reply * ) message->data;
2746
- if ( ( ntohs( stats_reply->flags ) & ~OFPSF_REPLY_MORE ) != 0 ) {
2747
- return ERROR_INVALID_STATS_REPLY_FLAGS;
2748
- }
2749
-
2750
- tables_length = ( uint16_t ) ( ntohs( stats_reply->header.length )
2751
- - offsetof( struct ofp_stats_reply, body ) );
2752
- if ( tables_length % sizeof( struct ofp_table_stats ) != 0 ) {
2753
- return ERROR_INVALID_LENGTH;
2754
- }
2755
-
2756
- offset = offsetof( struct ofp_stats_reply, body );
2757
- table_stats = ( struct ofp_table_stats * ) ( ( char * ) message->data + offset );
2758
-
2759
- n_tables = tables_length / sizeof( struct ofp_table_stats );
2760
-
2761
- for ( i = 0; i < n_tables; i++ ) {
2762
- // table_stats->table_id
2763
-
2764
- ret = validate_wildcards( ntohl( table_stats->wildcards ) );
2765
- if ( ret < 0 ) {
2766
- return ret;
2767
- }
2768
-
2769
- // table_stats->max_entries
2770
- // table_stats->active_count
2771
- // table_stats->lookup_count
2772
- // table_stats->matched_count
2773
-
2774
- table_stats++;
2775
- }
2776
-
2777
- return 0;
2778
- }
2779
-
2780
-
2781
- int
2782
- validate_port_stats_reply( const buffer *message ) {
2783
- int i;
2784
- int ret;
2785
- uint16_t ports_length;
2786
- uint16_t n_ports;
2787
- uint16_t offset;
2788
- struct ofp_stats_reply *stats_reply;
2789
- struct ofp_port_stats *port_stats;
2790
-
2791
- assert( message != NULL );
2792
-
2793
- ret = validate_header( message, OFPT_STATS_REPLY,
2794
- offsetof( struct ofp_stats_reply, body ),
2795
- UINT16_MAX );
2796
- if ( ret < 0 ) {
2797
- return ret;
2798
- }
2799
-
2800
- stats_reply = ( struct ofp_stats_reply * ) message->data;
2801
- if ( ( ntohs( stats_reply->flags ) & ~OFPSF_REPLY_MORE ) != 0 ) {
2802
- return ERROR_INVALID_STATS_REPLY_FLAGS;
2803
- }
2804
-
2805
- ports_length = ( uint16_t ) ( ntohs( stats_reply->header.length )
2806
- - offsetof( struct ofp_stats_reply, body ) );
2807
- if ( ports_length % sizeof( struct ofp_port_stats ) != 0 ) {
2808
- return ERROR_INVALID_LENGTH;
2809
- }
2810
-
2811
- offset = offsetof( struct ofp_stats_reply, body );
2812
- port_stats = ( struct ofp_port_stats * ) ( ( char * ) message->data + offset );
2813
-
2814
- n_ports = ports_length / sizeof( struct ofp_port_stats );
2815
- for ( i = 0; i < n_ports; i++ ) {
2816
- ret = validate_phy_port_no( ntohs( port_stats->port_no ) );
2817
-
2818
- if ( ret < 0 ) {
2819
- return ret;
2820
- }
2821
-
2822
- // port_stats->rx_packets
2823
- // port_stats->tx_packets
2824
- // port_stats->rx_bytes
2825
- // port_stats->tx_bytes
2826
- // port_stats->rx_dropped
2827
- // port_stats->tx_dropped
2828
- // port_stats->rx_errors
2829
- // port_stats->tx_errors
2830
- // port_stats->rx_frame_err
2831
- // port_stats->rx_over_err
2832
- // port_stats->rx_crc_err
2833
- // port_stats->collisions
2834
-
2835
- port_stats++;
2836
- }
2837
-
2838
- return 0;
2839
- }
2840
-
2841
-
2842
- int
2843
- validate_queue_stats_reply( const buffer *message ) {
2844
- int i;
2845
- int ret;
2846
- uint16_t queues_length;
2847
- uint16_t n_queues;
2848
- uint16_t offset;
2849
- struct ofp_stats_reply *stats_reply;
2850
- struct ofp_queue_stats *queue_stats;
2851
-
2852
- assert( message != NULL );
2853
-
2854
- ret = validate_header( message, OFPT_STATS_REPLY,
2855
- offsetof( struct ofp_stats_reply, body ),
2856
- UINT16_MAX );
2857
- if ( ret < 0 ) {
2858
- return ret;
2859
- }
2860
-
2861
- stats_reply = ( struct ofp_stats_reply * ) message->data;
2862
- if ( ( ntohs( stats_reply->flags ) & ~OFPSF_REPLY_MORE ) != 0 ) {
2863
- return ERROR_INVALID_STATS_REPLY_FLAGS;
2864
- }
2865
-
2866
- queues_length = ( uint16_t ) ( ntohs( stats_reply->header.length )
2867
- - offsetof( struct ofp_stats_reply, body ) );
2868
- if ( queues_length % sizeof( struct ofp_queue_stats ) != 0 ) {
2869
- return ERROR_INVALID_LENGTH;
2870
- }
2871
-
2872
- offset = offsetof( struct ofp_stats_reply, body );
2873
- queue_stats = ( struct ofp_queue_stats * ) ( ( char * ) message->data + offset );
2874
-
2875
- n_queues = queues_length / sizeof( struct ofp_queue_stats );
2876
- for ( i = 0; i < n_queues; i++ ) {
2877
- ret = validate_phy_port_no( ntohs( queue_stats->port_no ) );
2878
- if ( ret < 0 ) {
2879
- return ret;
2880
- }
2881
-
2882
- // queue_stats->queue_id
2883
- // queue_stats->tx_bytes
2884
- // queue_stats->tx_packets
2885
- // queue_stats->tx_errors
2886
-
2887
- queue_stats++;
2888
- }
2889
-
2890
- return 0;
2891
- }
2892
-
2893
-
2894
- int
2895
- validate_vendor_stats_reply( const buffer *message ) {
2896
- void *body;
2897
- int ret;
2898
- uint16_t body_length;
2899
- uint16_t offset;
2900
- struct ofp_stats_reply *stats_reply;
2901
-
2902
- assert( message != NULL );
2903
-
2904
- ret = validate_header( message, OFPT_STATS_REPLY,
2905
- offsetof( struct ofp_stats_reply, body ),
2906
- UINT16_MAX );
2907
- if ( ret < 0 ) {
2908
- return ret;
2909
- }
2910
-
2911
- stats_reply = ( struct ofp_stats_reply * ) message->data;
2912
-
2913
- if ( ( ntohs( stats_reply->flags ) & ~OFPSF_REPLY_MORE ) != 0 ) {
2914
- return ERROR_INVALID_STATS_REPLY_FLAGS;
2915
- }
2916
-
2917
- body_length = ( uint16_t ) ( ntohs( stats_reply->header.length )
2918
- - offsetof( struct ofp_stats_reply, body ) );
2919
-
2920
- offset = offsetof( struct ofp_stats_reply, body );
2921
- body = ( void * ) ( ( char * ) message->data + offset );
2922
- if ( ( body_length > 0 ) && ( body != NULL ) ) {
2923
- // FIXME: validate body here
2924
- }
2925
-
2926
- return 0;
2927
- }
2928
-
2929
-
2930
- int
2931
- validate_stats_reply( const buffer *message ) {
2932
- struct ofp_stats_reply *reply;
2933
-
2934
- assert( message != NULL );
2935
- assert( message->data != NULL );
2936
-
2937
- reply = ( struct ofp_stats_reply * ) message->data;
2938
-
2939
- // TODO: if ( reply->header.type != OFPT_STATS_REPLY ) { ... }
2940
-
2941
- switch ( ntohs( reply->type ) ) {
2942
- case OFPST_DESC:
2943
- return validate_desc_stats_reply( message );
2944
- case OFPST_FLOW:
2945
- return validate_flow_stats_reply( message );
2946
- case OFPST_AGGREGATE:
2947
- return validate_aggregate_stats_reply( message );
2948
- case OFPST_TABLE:
2949
- return validate_table_stats_reply( message );
2950
- case OFPST_PORT:
2951
- return validate_port_stats_reply( message );
2952
- case OFPST_QUEUE:
2953
- return validate_queue_stats_reply( message );
2954
- case OFPST_VENDOR:
2955
- return validate_vendor_stats_reply( message );
2956
- default:
2957
- break;
2958
- }
2959
-
2960
- return ERROR_UNSUPPORTED_STATS_TYPE;
2961
- }
2962
-
2963
-
2964
- int
2965
- validate_barrier_request( const buffer *message ) {
2966
- return validate_header( message, OFPT_BARRIER_REQUEST, sizeof( struct ofp_header ),
2967
- sizeof( struct ofp_header ) );
2968
- }
2969
-
2970
-
2971
- int
2972
- validate_barrier_reply( const buffer *message ) {
2973
- return validate_header( message, OFPT_BARRIER_REPLY, sizeof( struct ofp_header ),
2974
- sizeof( struct ofp_header ) );
2975
- }
2976
-
2977
-
2978
- int
2979
- validate_queue_get_config_request( const buffer *message ) {
2980
- int ret;
2981
- struct ofp_queue_get_config_request *queue_get_config_request;
2982
-
2983
- ret = validate_header( message, OFPT_QUEUE_GET_CONFIG_REQUEST,
2984
- sizeof( struct ofp_queue_get_config_request ),
2985
- sizeof( struct ofp_queue_get_config_request ) );
2986
- if ( ret < 0 ) {
2987
- return ret;
2988
- }
2989
-
2990
- queue_get_config_request = ( struct ofp_queue_get_config_request * ) message->data;
2991
-
2992
- ret = validate_phy_port_no( ntohs( queue_get_config_request->port ) );
2993
- if ( ret < 0 ) {
2994
- return ret;
2995
- }
2996
-
2997
- return 0;
2998
- }
2999
-
3000
-
3001
- static int
3002
- validate_queue_property( const struct ofp_queue_prop_header *property ) {
3003
- uint16_t property_length = ntohs( property->len );
3004
-
3005
- if ( property_length < sizeof( struct ofp_queue_prop_header ) ) {
3006
- return ERROR_TOO_SHORT_QUEUE_PROPERTY;
3007
- }
3008
-
3009
- switch ( ntohs( property->property ) ) {
3010
- case OFPQT_NONE:
3011
- if ( property_length < sizeof( struct ofp_queue_prop_header ) ) {
3012
- return ERROR_TOO_SHORT_QUEUE_PROPERTY;
3013
- }
3014
- else if ( property_length > sizeof( struct ofp_queue_prop_header ) ) {
3015
- return ERROR_TOO_LONG_QUEUE_PROPERTY;
3016
- }
3017
- break;
3018
- case OFPQT_MIN_RATE:
3019
- if ( property_length < sizeof( struct ofp_queue_prop_min_rate ) ) {
3020
- return ERROR_TOO_SHORT_QUEUE_PROPERTY;
3021
- }
3022
- else if ( property_length > sizeof( struct ofp_queue_prop_min_rate ) ) {
3023
- return ERROR_TOO_LONG_QUEUE_PROPERTY;
3024
- }
3025
- break;
3026
- default:
3027
- return ERROR_UNDEFINED_QUEUE_PROPERTY;
3028
- }
3029
-
3030
- return 0;
3031
- }
3032
-
3033
-
3034
- static int
3035
- validate_queue_properties( struct ofp_queue_prop_header *prop_head,
3036
- const uint16_t properties_length ) {
3037
- int ret;
3038
- uint16_t offset = 0;
3039
- struct ofp_queue_prop_header *property;
3040
-
3041
- property = prop_head;
3042
- while ( offset < properties_length ) {
3043
- ret = validate_queue_property( property );
3044
- if ( ret < 0 ) {
3045
- return ret;
3046
- }
3047
-
3048
- offset = ( uint16_t ) ( offset + ntohs( property->len ) );
3049
- property = ( struct ofp_queue_prop_header * ) ( ( char * ) prop_head + offset );
3050
- }
3051
-
3052
- return 0;
3053
- }
3054
-
3055
-
3056
- static int
3057
- validate_packet_queue( struct ofp_packet_queue *queue ) {
3058
- int ret;
3059
- uint16_t properties_length;
3060
- struct ofp_queue_prop_header *prop_head;
3061
-
3062
- assert( queue != NULL );
3063
-
3064
- // queue->queue_id
3065
-
3066
- if ( ntohs( queue->len ) < ( offsetof( struct ofp_packet_queue, properties )
3067
- + sizeof( struct ofp_queue_prop_header ) ) ) {
3068
- return ERROR_TOO_SHORT_QUEUE_DESCRIPTION;
3069
- }
3070
-
3071
- prop_head = ( struct ofp_queue_prop_header * ) ( ( char * ) queue
3072
- + offsetof( struct ofp_packet_queue, properties ) );
3073
- properties_length = ( uint16_t ) ( ntohs( queue->len )
3074
- - offsetof( struct ofp_packet_queue, properties ) );
3075
-
3076
- ret = validate_queue_properties( prop_head, properties_length );
3077
- if ( ret < 0 ) {
3078
- return ret;
3079
- }
3080
-
3081
- return 0;
3082
- }
3083
-
3084
-
3085
- static int
3086
- validate_packet_queues( struct ofp_packet_queue *queue_head, const int n_queues ) {
3087
- int i;
3088
- int ret;
3089
- struct ofp_packet_queue *queue;
3090
-
3091
- assert( queue_head != NULL );
3092
-
3093
- queue = queue_head;
3094
- for ( i = 0; i < n_queues; i++ ) {
3095
- ret = validate_packet_queue( queue );
3096
- if ( ret < 0 ) {
3097
- return ret;
3098
- }
3099
- queue = ( struct ofp_packet_queue * ) ( ( char * ) queue + ntohs( queue->len ) );
3100
- }
3101
-
3102
- return 0;
3103
- }
3104
-
3105
-
3106
- int
3107
- validate_queue_get_config_reply( const buffer *message ) {
3108
- int ret;
3109
- int n_queues = 0;
3110
- uint16_t queues_length;
3111
- struct ofp_queue_get_config_reply *queue_get_config_reply;
3112
- struct ofp_packet_queue *queue_head, *queue;
3113
-
3114
- assert( message != NULL );
3115
-
3116
- ret = validate_header( message, OFPT_QUEUE_GET_CONFIG_REPLY,
3117
- sizeof( struct ofp_queue_get_config_reply ) + sizeof( struct ofp_packet_queue ),
3118
- UINT16_MAX );
3119
- if ( ret < 0 ) {
3120
- return ret;
3121
- }
3122
-
3123
- queue_get_config_reply = ( struct ofp_queue_get_config_reply * ) message->data;
3124
-
3125
- ret = validate_phy_port_no( ntohs( queue_get_config_reply->port ) );
3126
- if ( ret < 0 ) {
3127
- return ret;
3128
- }
3129
-
3130
- queues_length = ( uint16_t ) ( ntohs( queue_get_config_reply->header.length )
3131
- - offsetof( struct ofp_queue_get_config_reply, queues ) );
3132
-
3133
- queue_head = ( struct ofp_packet_queue * ) ( ( char * ) message->data
3134
- + offsetof( struct ofp_queue_get_config_reply, queues ) );
3135
-
3136
- queue = queue_head;
3137
- while ( queues_length > offsetof( struct ofp_packet_queue, properties ) ) {
3138
- queues_length = ( uint16_t ) ( queues_length - ntohs( queue->len ) );
3139
- queue = ( struct ofp_packet_queue * ) ( ( char * ) queue + ntohs( queue->len ) );
3140
- n_queues++;
3141
- }
3142
-
3143
- if ( queues_length != 0 ) {
3144
- return ERROR_INVALID_LENGTH;
3145
- }
3146
-
3147
- if ( n_queues > 0 ) {
3148
- ret = validate_packet_queues( queue_head, n_queues );
3149
- if ( ret < 0 ) {
3150
- return ret;
3151
- }
3152
- }
3153
-
3154
- return 0;
3155
- }
3156
-
3157
-
3158
- static int
3159
- validate_action( struct ofp_action_header *action ) {
3160
- if ( ntohs( action->len ) < sizeof( struct ofp_action_header ) ) {
3161
- return ERROR_TOO_SHORT_ACTION;
3162
- }
3163
-
3164
- switch ( ntohs( action->type ) ) {
3165
- case OFPAT_OUTPUT:
3166
- return validate_action_output( ( struct ofp_action_output * ) action );
3167
- case OFPAT_SET_VLAN_VID:
3168
- return validate_action_set_vlan_vid( ( struct ofp_action_vlan_vid * ) action );
3169
- case OFPAT_SET_VLAN_PCP:
3170
- return validate_action_set_vlan_pcp( ( struct ofp_action_vlan_pcp * ) action );
3171
- case OFPAT_STRIP_VLAN:
3172
- return validate_action_strip_vlan( ( struct ofp_action_header * ) action );
3173
- case OFPAT_SET_DL_SRC:
3174
- return validate_action_set_dl_src( ( struct ofp_action_dl_addr * ) action );
3175
- case OFPAT_SET_DL_DST:
3176
- return validate_action_set_dl_dst( ( struct ofp_action_dl_addr * ) action );
3177
- case OFPAT_SET_NW_SRC:
3178
- return validate_action_set_nw_src( ( struct ofp_action_nw_addr * ) action );
3179
- case OFPAT_SET_NW_DST:
3180
- return validate_action_set_nw_dst( ( struct ofp_action_nw_addr * ) action );
3181
- case OFPAT_SET_NW_TOS:
3182
- return validate_action_set_nw_tos( ( struct ofp_action_nw_tos * ) action );
3183
- case OFPAT_SET_TP_SRC:
3184
- return validate_action_set_tp_src( ( struct ofp_action_tp_port * ) action );
3185
- case OFPAT_SET_TP_DST:
3186
- return validate_action_set_tp_dst( ( struct ofp_action_tp_port * ) action );
3187
- case OFPAT_ENQUEUE:
3188
- return validate_action_enqueue( ( struct ofp_action_enqueue * ) action );
3189
- case OFPAT_VENDOR:
3190
- return validate_action_vendor( ( struct ofp_action_vendor_header * ) action );
3191
- default:
3192
- break;
3193
- }
3194
-
3195
- return ERROR_UNDEFINED_ACTION_TYPE;
3196
- }
3197
-
3198
-
3199
- int
3200
- validate_actions( struct ofp_action_header *actions_head, const uint16_t length ) {
3201
- int ret;
3202
- uint16_t offset = 0;
3203
- struct ofp_action_header *action;
3204
-
3205
- action = actions_head;
3206
- while ( offset < length ) {
3207
- ret = validate_action( action );
3208
- if ( ret < 0 ) {
3209
- return ret;
3210
- }
3211
-
3212
- offset = ( uint16_t ) ( offset + ntohs( action->len ) );
3213
- action = ( struct ofp_action_header * ) ( ( char * ) actions_head + offset );
3214
- }
3215
-
3216
- return 0;
3217
- }
3218
-
3219
-
3220
- int
3221
- validate_action_output( const struct ofp_action_output *action ) {
3222
- int ret;
3223
- struct ofp_action_output output;
3224
-
3225
- ntoh_action_output( &output, action );
3226
- if ( output.type != OFPAT_OUTPUT ) {
3227
- return ERROR_INVALID_ACTION_TYPE;
3228
- }
3229
- if ( output.len < sizeof( struct ofp_action_output ) ) {
3230
- return ERROR_TOO_SHORT_ACTION_OUTPUT;
3231
- }
3232
- else if ( output.len > sizeof( struct ofp_action_output ) ) {
3233
- return ERROR_TOO_LONG_ACTION_OUTPUT;
3234
- }
3235
-
3236
- ret = validate_out_port_no( output.port );
3237
- if ( ret < 0 ) {
3238
- return ret;
3239
- }
3240
-
3241
- // output.max_len
3242
-
3243
- return 0;
3244
- }
3245
-
3246
-
3247
- int
3248
- validate_action_set_vlan_vid( const struct ofp_action_vlan_vid *action ) {
3249
- int ret;
3250
- struct ofp_action_vlan_vid vlan_vid;
3251
-
3252
- ntoh_action_vlan_vid( &vlan_vid, action );
3253
-
3254
- if ( vlan_vid.type != OFPAT_SET_VLAN_VID ) {
3255
- return ERROR_INVALID_ACTION_TYPE;
3256
- }
3257
- if ( vlan_vid.len < sizeof( struct ofp_action_vlan_vid ) ) {
3258
- return ERROR_TOO_SHORT_ACTION_VLAN_VID;
3259
- }
3260
- else if ( vlan_vid.len > sizeof( struct ofp_action_vlan_vid ) ) {
3261
- return ERROR_TOO_LONG_ACTION_VLAN_VID;
3262
- }
3263
-
3264
- ret = validate_vlan_vid( vlan_vid.vlan_vid );
3265
- if ( ret < 0 ) {
3266
- return ret;
3267
- }
3268
-
3269
- return 0;
3270
- }
3271
-
3272
-
3273
- int
3274
- validate_action_set_vlan_pcp( const struct ofp_action_vlan_pcp *action ) {
3275
- int ret;
3276
- struct ofp_action_vlan_pcp vlan_pcp;
3277
-
3278
- ntoh_action_vlan_pcp( &vlan_pcp, action );
3279
-
3280
- if ( vlan_pcp.type != OFPAT_SET_VLAN_PCP ) {
3281
- return ERROR_INVALID_ACTION_TYPE;
3282
- }
3283
- if ( vlan_pcp.len < sizeof( struct ofp_action_vlan_pcp ) ) {
3284
- return ERROR_TOO_SHORT_ACTION_VLAN_PCP;
3285
- }
3286
- else if ( vlan_pcp.len > sizeof( struct ofp_action_vlan_pcp ) ) {
3287
- return ERROR_TOO_LONG_ACTION_VLAN_PCP;
3288
- }
3289
-
3290
- ret = validate_vlan_pcp( vlan_pcp.vlan_pcp );
3291
- if ( ret < 0 ) {
3292
- return ret;
3293
- }
3294
-
3295
- return 0;
3296
- }
3297
-
3298
-
3299
- int
3300
- validate_action_strip_vlan( const struct ofp_action_header *action ) {
3301
- struct ofp_action_header strip_vlan;
3302
-
3303
- ntoh_action_strip_vlan( &strip_vlan, action );
3304
-
3305
- if ( strip_vlan.type != OFPAT_STRIP_VLAN ) {
3306
- return ERROR_INVALID_ACTION_TYPE;
3307
- }
3308
- if ( strip_vlan.len < sizeof( struct ofp_action_header ) ) {
3309
- return ERROR_TOO_SHORT_ACTION_STRIP_VLAN;
3310
- }
3311
- else if ( strip_vlan.len > sizeof( struct ofp_action_header ) ) {
3312
- return ERROR_TOO_LONG_ACTION_STRIP_VLAN;
3313
- }
3314
-
3315
- return 0;
3316
- }
3317
-
3318
-
3319
- int
3320
- validate_action_set_dl_src( const struct ofp_action_dl_addr *action ) {
3321
- struct ofp_action_dl_addr dl_src;
3322
-
3323
- ntoh_action_dl_addr( &dl_src, action );
3324
-
3325
- if ( dl_src.type != OFPAT_SET_DL_SRC ) {
3326
- return ERROR_INVALID_ACTION_TYPE;
3327
- }
3328
- if ( dl_src.len < sizeof( struct ofp_action_dl_addr ) ) {
3329
- return ERROR_TOO_SHORT_ACTION_DL_SRC;
3330
- }
3331
- else if ( dl_src.len > sizeof( struct ofp_action_dl_addr ) ) {
3332
- return ERROR_TOO_LONG_ACTION_DL_SRC;
3333
- }
3334
-
3335
- return 0;
3336
- }
3337
-
3338
-
3339
- int
3340
- validate_action_set_dl_dst( const struct ofp_action_dl_addr *action ) {
3341
- struct ofp_action_dl_addr dl_dst;
3342
-
3343
- ntoh_action_dl_addr( &dl_dst, action );
3344
-
3345
- if ( dl_dst.type != OFPAT_SET_DL_DST ) {
3346
- return ERROR_INVALID_ACTION_TYPE;
3347
- }
3348
- if ( dl_dst.len < sizeof( struct ofp_action_dl_addr ) ) {
3349
- return ERROR_TOO_SHORT_ACTION_DL_DST;
3350
- }
3351
- else if ( dl_dst.len > sizeof( struct ofp_action_dl_addr ) ) {
3352
- return ERROR_TOO_LONG_ACTION_DL_DST;
3353
- }
3354
-
3355
- return 0;
3356
- }
3357
-
3358
-
3359
- int
3360
- validate_action_set_nw_src( const struct ofp_action_nw_addr *action ) {
3361
- struct ofp_action_nw_addr nw_src;
3362
-
3363
- ntoh_action_nw_addr( &nw_src, action );
3364
-
3365
- if ( nw_src.type != OFPAT_SET_NW_SRC ) {
3366
- return ERROR_INVALID_ACTION_TYPE;
3367
- }
3368
- if ( nw_src.len < sizeof( struct ofp_action_nw_addr ) ) {
3369
- return ERROR_TOO_SHORT_ACTION_NW_SRC;
3370
- }
3371
- else if ( nw_src.len > sizeof( struct ofp_action_nw_addr ) ) {
3372
- return ERROR_TOO_LONG_ACTION_NW_SRC;
3373
- }
3374
-
3375
- return 0;
3376
- }
3377
-
3378
-
3379
- int
3380
- validate_action_set_nw_dst( const struct ofp_action_nw_addr *action ) {
3381
- struct ofp_action_nw_addr nw_dst;
3382
-
3383
- ntoh_action_nw_addr( &nw_dst, action );
3384
-
3385
- if ( nw_dst.type != OFPAT_SET_NW_DST ) {
3386
- return ERROR_INVALID_ACTION_TYPE;
3387
- }
3388
- if ( nw_dst.len < sizeof( struct ofp_action_nw_addr ) ) {
3389
- return ERROR_TOO_SHORT_ACTION_NW_DST;
3390
- }
3391
- else if ( nw_dst.len > sizeof( struct ofp_action_nw_addr ) ) {
3392
- return ERROR_TOO_LONG_ACTION_NW_DST;
3393
- }
3394
-
3395
- return 0;
3396
- }
3397
-
3398
-
3399
- int
3400
- validate_action_set_nw_tos( const struct ofp_action_nw_tos *action ) {
3401
- int ret;
3402
- struct ofp_action_nw_tos nw_tos;
3403
-
3404
- ntoh_action_nw_tos( &nw_tos, action );
3405
-
3406
- if ( nw_tos.type != OFPAT_SET_NW_TOS ) {
3407
- return ERROR_INVALID_ACTION_TYPE;
3408
- }
3409
- if ( nw_tos.len < sizeof( struct ofp_action_nw_addr ) ) {
3410
- return ERROR_TOO_SHORT_ACTION_NW_TOS;
3411
- }
3412
- else if ( nw_tos.len > sizeof( struct ofp_action_nw_addr ) ) {
3413
- return ERROR_TOO_LONG_ACTION_NW_TOS;
3414
- }
3415
-
3416
- ret = validate_nw_tos( nw_tos.nw_tos );
3417
- if ( ret < 0 ) {
3418
- return ret;
3419
- }
3420
-
3421
- return 0;
3422
- }
3423
-
3424
-
3425
- int
3426
- validate_action_set_tp_src( const struct ofp_action_tp_port *action ) {
3427
- struct ofp_action_tp_port tp_src;
3428
-
3429
- ntoh_action_tp_port( &tp_src, action );
3430
-
3431
- if ( tp_src.type != OFPAT_SET_TP_SRC ) {
3432
- return ERROR_INVALID_ACTION_TYPE;
3433
- }
3434
- if ( tp_src.len < sizeof( struct ofp_action_tp_port ) ) {
3435
- return ERROR_TOO_SHORT_ACTION_TP_SRC;
3436
- }
3437
- else if ( tp_src.len > sizeof( struct ofp_action_tp_port ) ) {
3438
- return ERROR_TOO_LONG_ACTION_TP_SRC;
3439
- }
3440
-
3441
- return 0;
3442
- }
3443
-
3444
-
3445
- int
3446
- validate_action_set_tp_dst( const struct ofp_action_tp_port *action ) {
3447
- struct ofp_action_tp_port tp_dst;
3448
-
3449
- ntoh_action_tp_port( &tp_dst, action );
3450
-
3451
- if ( tp_dst.type != OFPAT_SET_TP_DST ) {
3452
- return ERROR_INVALID_ACTION_TYPE;
3453
- }
3454
- if ( tp_dst.len < sizeof( struct ofp_action_tp_port ) ) {
3455
- return ERROR_TOO_SHORT_ACTION_TP_DST;
3456
- }
3457
- else if ( tp_dst.len > sizeof( struct ofp_action_tp_port ) ) {
3458
- return ERROR_TOO_LONG_ACTION_TP_DST;
3459
- }
3460
-
3461
- return 0;
3462
- }
3463
-
3464
-
3465
- int
3466
- validate_action_enqueue( const struct ofp_action_enqueue *action ) {
3467
- int ret;
3468
- struct ofp_action_enqueue enqueue;
3469
-
3470
- ntoh_action_enqueue( &enqueue, action );
3471
-
3472
- if ( enqueue.type != OFPAT_ENQUEUE ) {
3473
- return ERROR_INVALID_ACTION_TYPE;
3474
- }
3475
- if ( enqueue.len < sizeof( struct ofp_action_enqueue ) ) {
3476
- return ERROR_TOO_SHORT_ACTION_ENQUEUE;
3477
- }
3478
- else if ( enqueue.len > sizeof( struct ofp_action_enqueue ) ) {
3479
- return ERROR_TOO_LONG_ACTION_ENQUEUE;
3480
- }
3481
-
3482
- ret = validate_phy_port_no( enqueue.port );
3483
- if ( ret < 0 ) {
3484
- return ret;
3485
- }
3486
-
3487
- // enqueue.queue_id
3488
-
3489
- return 0;
3490
- }
3491
-
3492
-
3493
- int
3494
- validate_action_vendor( const struct ofp_action_vendor_header *action ) {
3495
- if ( ntohs( action->type ) != OFPAT_VENDOR ) {
3496
- return ERROR_INVALID_ACTION_TYPE;
3497
- }
3498
- if ( ntohs( action->len ) < sizeof( struct ofp_action_vendor_header ) ) {
3499
- return ERROR_TOO_SHORT_ACTION_VENDOR;
3500
- }
3501
- else if ( ntohs( action->len ) % 8 != 0 ) {
3502
- return ERROR_INVALID_LENGTH_ACTION_VENDOR;
3503
- }
3504
-
3505
- // action->vendor
3506
-
3507
- return 0;
3508
- }
3509
-
3510
-
3511
- int
3512
- validate_openflow_message( const buffer *message ) {
3513
- int ret;
3514
-
3515
- assert( message != NULL );
3516
- assert( message->data != NULL );
3517
-
3518
- struct ofp_header *header = ( struct ofp_header * ) message->data;
3519
-
3520
- debug( "Validating an OpenFlow message ( version = %#x, type = %#x, length = %u, xid = %#x ).",
3521
- header->version, header->type, ntohs( header->length ), ntohl( header->xid ) );
3522
-
3523
- switch ( header->type ) {
3524
- case OFPT_HELLO:
3525
- ret = validate_hello( message );
3526
- break;
3527
- case OFPT_ERROR:
3528
- ret = validate_error( message );
3529
- break;
3530
- case OFPT_ECHO_REQUEST:
3531
- ret = validate_echo_request( message );
3532
- break;
3533
- case OFPT_ECHO_REPLY:
3534
- ret = validate_echo_reply( message );
3535
- break;
3536
- case OFPT_VENDOR:
3537
- ret = validate_vendor( message );
3538
- break;
3539
- case OFPT_FEATURES_REQUEST:
3540
- ret = validate_features_request( message );
3541
- break;
3542
- case OFPT_FEATURES_REPLY:
3543
- ret = validate_features_reply( message );
3544
- break;
3545
- case OFPT_GET_CONFIG_REQUEST:
3546
- ret = validate_get_config_request( message );
3547
- break;
3548
- case OFPT_GET_CONFIG_REPLY:
3549
- ret = validate_get_config_reply( message );
3550
- break;
3551
- case OFPT_SET_CONFIG:
3552
- ret = validate_set_config( message );
3553
- break;
3554
- case OFPT_PACKET_IN:
3555
- ret = validate_packet_in( message );
3556
- break;
3557
- case OFPT_FLOW_REMOVED:
3558
- ret = validate_flow_removed( message );
3559
- break;
3560
- case OFPT_PORT_STATUS:
3561
- ret = validate_port_status( message );
3562
- break;
3563
- case OFPT_PACKET_OUT:
3564
- ret = validate_packet_out( message );
3565
- break;
3566
- case OFPT_FLOW_MOD:
3567
- ret = validate_flow_mod( message );
3568
- break;
3569
- case OFPT_PORT_MOD:
3570
- ret = validate_port_mod( message );
3571
- break;
3572
- case OFPT_STATS_REQUEST:
3573
- ret = validate_stats_request( message );
3574
- break;
3575
- case OFPT_STATS_REPLY:
3576
- ret = validate_stats_reply( message );
3577
- break;
3578
- case OFPT_BARRIER_REQUEST:
3579
- ret = validate_barrier_request( message );
3580
- break;
3581
- case OFPT_BARRIER_REPLY:
3582
- ret = validate_barrier_reply( message );
3583
- break;
3584
- case OFPT_QUEUE_GET_CONFIG_REQUEST:
3585
- ret = validate_queue_get_config_request( message );
3586
- break;
3587
- case OFPT_QUEUE_GET_CONFIG_REPLY:
3588
- ret = validate_queue_get_config_reply( message );
3589
- break;
3590
- default:
3591
- ret = ERROR_UNDEFINED_TYPE;
3592
- break;
3593
- }
3594
-
3595
- debug( "Validation completed ( ret = %d ).", ret );
3596
-
3597
- return ret;
3598
- }
3599
-
3600
-
3601
- bool
3602
- valid_openflow_message( const buffer *message ) {
3603
- if ( validate_openflow_message( message ) < 0 ) {
3604
- return false;
3605
- }
3606
-
3607
- return true;
3608
- }
3609
-
3610
-
3611
- static struct error_map {
3612
- uint8_t type; // One of the OFPT_ constants.
3613
- struct map {
3614
- int error_no; // Internal error number.
3615
- uint16_t error_type; // OpenFlow error type.
3616
- uint16_t error_code; // OpenFlow error code.
3617
- } maps[ 64 ];
3618
- } error_maps[] = {
3619
- {
3620
- OFPT_HELLO,
3621
- {
3622
- { ERROR_UNSUPPORTED_VERSION, OFPET_HELLO_FAILED, OFPHFC_INCOMPATIBLE },
3623
- { ERROR_TOO_SHORT_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3624
- { ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3625
- { ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3626
- { ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3627
- { 0, 0, 0 },
3628
- }
3629
- },
3630
- {
3631
- OFPT_ERROR,
3632
- {
3633
- { ERROR_UNSUPPORTED_VERSION, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION },
3634
- { ERROR_TOO_SHORT_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3635
- { ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3636
- { ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3637
- { ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3638
- { ERROR_INVALID_ERROR_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3639
- { ERROR_INVALID_ERROR_CODE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3640
- { 0, 0, 0 },
3641
- }
3642
- },
3643
- {
3644
- OFPT_ECHO_REQUEST,
3645
- {
3646
- { ERROR_UNSUPPORTED_VERSION, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION },
3647
- { ERROR_TOO_SHORT_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3648
- { ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3649
- { ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3650
- { ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3651
- { 0, 0, 0 },
3652
- }
3653
- },
3654
- {
3655
- OFPT_ECHO_REPLY,
3656
- {
3657
- { ERROR_UNSUPPORTED_VERSION, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION },
3658
- { ERROR_TOO_SHORT_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3659
- { ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3660
- { ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3661
- { ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3662
- { 0, 0, 0 },
3663
- }
3664
- },
3665
- {
3666
- OFPT_VENDOR,
3667
- {
3668
- { ERROR_UNSUPPORTED_VERSION, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION },
3669
- { ERROR_TOO_SHORT_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3670
- { ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3671
- { ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3672
- { ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3673
- { 0, 0, 0 },
3674
- }
3675
- },
3676
- {
3677
- OFPT_FEATURES_REQUEST,
3678
- {
3679
- { ERROR_UNSUPPORTED_VERSION, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION },
3680
- { ERROR_TOO_SHORT_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3681
- { ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3682
- { ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3683
- { ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3684
- { 0, 0, 0 },
3685
- }
3686
- },
3687
- {
3688
- OFPT_FEATURES_REPLY,
3689
- {
3690
- { ERROR_UNSUPPORTED_VERSION, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION },
3691
- { ERROR_TOO_SHORT_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3692
- { ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3693
- { ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3694
- { ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3695
- { 0, 0, 0 },
3696
- }
3697
- },
3698
- {
3699
- OFPT_GET_CONFIG_REQUEST,
3700
- {
3701
- { ERROR_UNSUPPORTED_VERSION, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION },
3702
- { ERROR_TOO_SHORT_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3703
- { ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3704
- { ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3705
- { ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3706
- { 0, 0, 0 },
3707
- }
3708
- },
3709
- {
3710
- OFPT_GET_CONFIG_REPLY,
3711
- {
3712
- { ERROR_UNSUPPORTED_VERSION, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION },
3713
- { ERROR_TOO_SHORT_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3714
- { ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3715
- { ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3716
- { ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3717
- { 0, 0, 0 },
3718
- }
3719
- },
3720
- {
3721
- OFPT_SET_CONFIG,
3722
- {
3723
- { ERROR_UNSUPPORTED_VERSION, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION },
3724
- { ERROR_TOO_SHORT_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3725
- { ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3726
- { ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3727
- { ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3728
- { ERROR_INVALID_SWITCH_CONFIG, OFPET_BAD_REQUEST, OFPBRC_EPERM }, // FIXME
3729
- { 0, 0, 0 },
3730
- }
3731
- },
3732
- {
3733
- OFPT_PACKET_IN, // FIXME: Should we return an error for packet_in ?
3734
- {
3735
- { ERROR_UNSUPPORTED_VERSION, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION },
3736
- { ERROR_TOO_SHORT_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3737
- { ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3738
- { ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3739
- { ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3740
- { ERROR_INVALID_PACKET_IN_REASON, OFPET_BAD_REQUEST, OFPBRC_EPERM }, // FIXME
3741
- { 0, 0, 0 },
3742
- }
3743
- },
3744
- {
3745
- OFPT_FLOW_REMOVED, // FIXME: Should we return an error for flow_removed ?
3746
- {
3747
- { ERROR_UNSUPPORTED_VERSION, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION },
3748
- { ERROR_TOO_SHORT_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3749
- { ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3750
- { ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3751
- { ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3752
- { ERROR_INVALID_FLOW_PRIORITY, OFPET_BAD_REQUEST, OFPBRC_EPERM }, // FIXME
3753
- { ERROR_INVALID_FLOW_REMOVED_REASON, OFPET_BAD_REQUEST, OFPBRC_EPERM }, // FIXME
3754
- { 0, 0, 0 },
3755
- }
3756
- },
3757
- {
3758
- OFPT_PORT_STATUS, // FIXME: Should we return an error for port_status ?
3759
- {
3760
- { ERROR_UNSUPPORTED_VERSION, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION },
3761
- { ERROR_TOO_SHORT_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3762
- { ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3763
- { ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3764
- { ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3765
- { ERROR_INVALID_PORT_STATUS_REASON, OFPET_BAD_REQUEST, OFPBRC_EPERM }, // FIXME
3766
- { 0, 0, 0 },
3767
- }
3768
- },
3769
- {
3770
- OFPT_PACKET_OUT,
3771
- {
3772
- { ERROR_UNSUPPORTED_VERSION, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION },
3773
- { ERROR_TOO_SHORT_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3774
- { ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3775
- { ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3776
- { ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3777
- { ERROR_INVALID_ACTION_TYPE, OFPET_BAD_ACTION, OFPBAC_BAD_TYPE },
3778
- { ERROR_TOO_SHORT_ACTION_OUTPUT, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3779
- { ERROR_TOO_LONG_ACTION_OUTPUT, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3780
- { ERROR_INVALID_PORT_NO, OFPET_BAD_ACTION, OFPBAC_BAD_OUT_PORT },
3781
- { ERROR_TOO_SHORT_ACTION_VLAN_VID, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3782
- { ERROR_TOO_LONG_ACTION_VLAN_VID, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3783
- { ERROR_INVALID_VLAN_VID, OFPET_BAD_ACTION, OFPBAC_BAD_ARGUMENT },
3784
- { ERROR_TOO_SHORT_ACTION_VLAN_PCP, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3785
- { ERROR_TOO_LONG_ACTION_VLAN_PCP, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3786
- { ERROR_INVALID_VLAN_PCP, OFPET_BAD_ACTION, OFPBAC_BAD_ARGUMENT },
3787
- { ERROR_TOO_SHORT_ACTION_STRIP_VLAN, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3788
- { ERROR_TOO_LONG_ACTION_STRIP_VLAN, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3789
- { ERROR_TOO_SHORT_ACTION_DL_SRC, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3790
- { ERROR_TOO_LONG_ACTION_DL_SRC, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3791
- { ERROR_TOO_SHORT_ACTION_DL_DST, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3792
- { ERROR_TOO_LONG_ACTION_DL_DST, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3793
- { ERROR_TOO_SHORT_ACTION_NW_SRC, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3794
- { ERROR_TOO_LONG_ACTION_NW_SRC, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3795
- { ERROR_TOO_SHORT_ACTION_NW_DST, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3796
- { ERROR_TOO_LONG_ACTION_NW_DST, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3797
- { ERROR_TOO_SHORT_ACTION_NW_TOS, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3798
- { ERROR_TOO_LONG_ACTION_NW_TOS, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3799
- { ERROR_TOO_SHORT_ACTION_TP_SRC, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3800
- { ERROR_TOO_LONG_ACTION_TP_SRC, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3801
- { ERROR_TOO_SHORT_ACTION_TP_DST, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3802
- { ERROR_TOO_LONG_ACTION_TP_DST, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3803
- { ERROR_TOO_SHORT_ACTION_ENQUEUE, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3804
- { ERROR_TOO_LONG_ACTION_ENQUEUE, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3805
- { ERROR_INVALID_PORT_NO, OFPET_BAD_ACTION, OFPBAC_BAD_OUT_PORT },
3806
- { ERROR_TOO_SHORT_ACTION_VENDOR, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3807
- { ERROR_INVALID_LENGTH_ACTION_VENDOR, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3808
- { ERROR_UNDEFINED_ACTION_TYPE, OFPET_BAD_ACTION, OFPBAC_BAD_TYPE },
3809
- { 0, 0, 0 },
3810
- }
3811
- },
3812
- {
3813
- OFPT_FLOW_MOD,
3814
- {
3815
- { ERROR_UNSUPPORTED_VERSION, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION },
3816
- { ERROR_TOO_SHORT_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3817
- { ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3818
- { ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3819
- { ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3820
- { ERROR_INVALID_ACTION_TYPE, OFPET_BAD_ACTION, OFPBAC_BAD_TYPE },
3821
- { ERROR_TOO_SHORT_ACTION_OUTPUT, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3822
- { ERROR_TOO_LONG_ACTION_OUTPUT, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3823
- { ERROR_INVALID_PORT_NO, OFPET_BAD_ACTION, OFPBAC_BAD_OUT_PORT },
3824
- { ERROR_TOO_SHORT_ACTION_VLAN_VID, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3825
- { ERROR_TOO_LONG_ACTION_VLAN_VID, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3826
- { ERROR_INVALID_VLAN_VID, OFPET_BAD_ACTION, OFPBAC_BAD_ARGUMENT },
3827
- { ERROR_TOO_SHORT_ACTION_VLAN_PCP, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3828
- { ERROR_TOO_LONG_ACTION_VLAN_PCP, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3829
- { ERROR_INVALID_VLAN_PCP, OFPET_BAD_ACTION, OFPBAC_BAD_ARGUMENT },
3830
- { ERROR_TOO_SHORT_ACTION_STRIP_VLAN, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3831
- { ERROR_TOO_LONG_ACTION_STRIP_VLAN, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3832
- { ERROR_TOO_SHORT_ACTION_DL_SRC, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3833
- { ERROR_TOO_LONG_ACTION_DL_SRC, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3834
- { ERROR_TOO_SHORT_ACTION_DL_DST, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3835
- { ERROR_TOO_LONG_ACTION_DL_DST, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3836
- { ERROR_TOO_SHORT_ACTION_NW_SRC, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3837
- { ERROR_TOO_LONG_ACTION_NW_SRC, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3838
- { ERROR_TOO_SHORT_ACTION_NW_DST, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3839
- { ERROR_TOO_LONG_ACTION_NW_DST, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3840
- { ERROR_TOO_SHORT_ACTION_NW_TOS, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3841
- { ERROR_TOO_LONG_ACTION_NW_TOS, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3842
- { ERROR_TOO_SHORT_ACTION_TP_SRC, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3843
- { ERROR_TOO_LONG_ACTION_TP_SRC, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3844
- { ERROR_TOO_SHORT_ACTION_TP_DST, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3845
- { ERROR_TOO_LONG_ACTION_TP_DST, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3846
- { ERROR_TOO_SHORT_ACTION_ENQUEUE, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3847
- { ERROR_TOO_LONG_ACTION_ENQUEUE, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3848
- { ERROR_INVALID_PORT_NO, OFPET_BAD_ACTION, OFPBAC_BAD_OUT_PORT },
3849
- { ERROR_TOO_SHORT_ACTION_VENDOR, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3850
- { ERROR_INVALID_LENGTH_ACTION_VENDOR, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3851
- { ERROR_UNDEFINED_ACTION_TYPE, OFPET_BAD_ACTION, OFPBAC_BAD_TYPE },
3852
- { ERROR_INVALID_WILDCARDS, OFPET_FLOW_MOD_FAILED, OFPFMFC_EPERM }, // FIXME
3853
- { ERROR_UNDEFINED_FLOW_MOD_COMMAND, OFPET_FLOW_MOD_FAILED, OFPFMFC_BAD_COMMAND },
3854
- { ERROR_INVALID_FLOW_PRIORITY, OFPET_FLOW_MOD_FAILED, OFPFMFC_EPERM }, // FIXME
3855
- { ERROR_INVALID_FLOW_MOD_FLAGS, OFPET_FLOW_MOD_FAILED, OFPFMFC_EPERM }, // FIXME
3856
- { 0, 0, 0 },
3857
- }
3858
- },
3859
- {
3860
- OFPT_PORT_MOD,
3861
- {
3862
- { ERROR_UNSUPPORTED_VERSION, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION },
3863
- { ERROR_TOO_SHORT_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3864
- { ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3865
- { ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3866
- { ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3867
- { ERROR_INVALID_PORT_NO, OFPET_PORT_MOD_FAILED, OFPPMFC_BAD_PORT },
3868
- { ERROR_INVALID_PORT_CONFIG, OFPET_BAD_REQUEST, OFPBRC_EPERM }, // FIXME
3869
- { ERROR_INVALID_PORT_MASK, OFPET_BAD_REQUEST, OFPBRC_EPERM }, // FIXME
3870
- { ERROR_INVALID_PORT_FEATURES, OFPET_BAD_REQUEST, OFPBRC_EPERM }, // FIXME
3871
- { 0, 0, 0 },
3872
- }
3873
- },
3874
- {
3875
- OFPT_STATS_REQUEST,
3876
- {
3877
- { ERROR_UNSUPPORTED_VERSION, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION },
3878
- { ERROR_TOO_SHORT_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3879
- { ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3880
- { ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3881
- { ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3882
- { ERROR_UNSUPPORTED_STATS_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_STAT },
3883
- { ERROR_INVALID_STATS_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_STAT },
3884
- { ERROR_INVALID_STATS_REQUEST_FLAGS, OFPET_BAD_REQUEST, OFPBRC_EPERM }, // FIXME
3885
- { ERROR_INVALID_PORT_NO, OFPET_BAD_REQUEST, OFPBRC_EPERM }, // FIXME
3886
- { ERROR_INVALID_WILDCARDS, OFPET_BAD_REQUEST, OFPBRC_EPERM }, // FIXME
3887
- { ERROR_INVALID_VLAN_VID, OFPET_BAD_REQUEST, OFPBRC_EPERM }, // FIXME
3888
- { ERROR_INVALID_VLAN_PCP, OFPET_BAD_REQUEST, OFPBRC_EPERM }, // FIXME
3889
- { ERROR_INVALID_NW_TOS, OFPET_BAD_REQUEST, OFPBRC_EPERM }, // FIXME
3890
- { 0, 0, 0 },
3891
- }
3892
- },
3893
- {
3894
- OFPT_STATS_REPLY,
3895
- {
3896
- { ERROR_UNSUPPORTED_VERSION, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION },
3897
- { ERROR_TOO_SHORT_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3898
- { ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3899
- { ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3900
- { ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3901
- { 0, 0, 0 },
3902
- }
3903
- },
3904
- {
3905
- OFPT_BARRIER_REQUEST,
3906
- {
3907
- { ERROR_UNSUPPORTED_VERSION, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION },
3908
- { ERROR_TOO_SHORT_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3909
- { ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3910
- { ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3911
- { ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3912
- { 0, 0, 0 },
3913
- }
3914
- },
3915
- {
3916
- OFPT_BARRIER_REPLY,
3917
- {
3918
- { ERROR_UNSUPPORTED_VERSION, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION },
3919
- { ERROR_TOO_SHORT_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3920
- { ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3921
- { ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3922
- { ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3923
- { 0, 0, 0 },
3924
- }
3925
- },
3926
- {
3927
- OFPT_QUEUE_GET_CONFIG_REQUEST,
3928
- {
3929
- { ERROR_UNSUPPORTED_VERSION, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION },
3930
- { ERROR_TOO_SHORT_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3931
- { ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3932
- { ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3933
- { ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3934
- { ERROR_INVALID_PORT_NO, OFPET_QUEUE_OP_FAILED, OFPQOFC_BAD_PORT },
3935
- { 0, 0, 0 },
3936
- }
3937
- },
3938
- {
3939
- OFPT_QUEUE_GET_CONFIG_REPLY,
3940
- {
3941
- { ERROR_UNSUPPORTED_VERSION, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION },
3942
- { ERROR_TOO_SHORT_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3943
- { ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
3944
- { ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3945
- { ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
3946
- { 0, 0, 0 },
3947
- }
3948
- },
3949
- };
3950
-
3951
-
3952
- bool
3953
- get_error_type_and_code( const uint8_t type, const int error_no,
3954
- uint16_t *error_type, uint16_t *error_code ) {
3955
- if ( type > OFPT_QUEUE_GET_CONFIG_REPLY ) {
3956
- *error_type = OFPET_BAD_REQUEST;
3957
- *error_code = OFPBRC_BAD_TYPE;
3958
- debug( "Undefined OpenFlow message type ( type = %u ).", type );
3959
- return true;
3960
- }
3961
-
3962
- int i = 0;
3963
- for ( i = 0; error_maps[ type ].maps[ i ].error_no != 0; i++ ) {
3964
- if ( error_no == error_maps[ type ].maps[ i ].error_no ) {
3965
- *error_type = error_maps[ type ].maps[ i ].error_type;
3966
- *error_code = error_maps[ type ].maps[ i ].error_code;
3967
- return true;
3968
- }
3969
- }
3970
-
3971
- return false;
3972
- }
3973
-
3974
-
3975
- void
3976
- set_match_from_packet( struct ofp_match *match, const uint16_t in_port,
3977
- const uint32_t wildcards, const buffer *packet ) {
3978
- // Note that wildcards must be filled before calling this function.
3979
-
3980
- assert( match != NULL );
3981
- assert( packet != NULL );
3982
- assert( packet->user_data != NULL );
3983
-
3984
- memset( match, 0, sizeof( struct ofp_match ) );
3985
- match->wildcards = wildcards;
3986
-
3987
- if ( !( wildcards & OFPFW_IN_PORT ) ) {
3988
- match->in_port = in_port;
3989
- }
3990
- if ( !( wildcards & OFPFW_DL_SRC ) ) {
3991
- memcpy( match->dl_src, ( ( packet_info * ) packet->user_data )->eth_macsa, OFP_ETH_ALEN );
3992
- }
3993
- if ( !( wildcards & OFPFW_DL_DST ) ) {
3994
- memcpy( match->dl_dst, ( ( packet_info * ) packet->user_data )->eth_macda, OFP_ETH_ALEN );
3995
- }
3996
- if ( !( wildcards & OFPFW_DL_VLAN ) ) {
3997
- if ( packet_type_eth_vtag( packet ) ) {
3998
- match->dl_vlan = ( ( packet_info * ) packet->user_data )->vlan_vid;
3999
- if ( ( match->dl_vlan & ~VLAN_VID_MASK ) != 0 ) {
4000
- warn( "Invalid vlan id ( change %#x to %#x )", match->dl_vlan, match->dl_vlan & VLAN_VID_MASK );
4001
- match->dl_vlan = ( uint16_t ) ( match->dl_vlan & VLAN_VID_MASK );
4002
- }
4003
- }
4004
- else {
4005
- match->dl_vlan = UINT16_MAX;
4006
- }
4007
- }
4008
- if ( !( wildcards & OFPFW_DL_VLAN_PCP ) ) {
4009
- if ( packet_type_eth_vtag( packet ) ) {
4010
- match->dl_vlan_pcp = ( ( packet_info * ) packet->user_data )->vlan_prio;
4011
- if ( ( match->dl_vlan_pcp & ~VLAN_PCP_MASK ) != 0 ) {
4012
- warn( "Invalid vlan pcp ( change %u to %u )", match->dl_vlan_pcp, match->dl_vlan_pcp & VLAN_PCP_MASK );
4013
- match->dl_vlan_pcp = ( uint8_t ) ( match->dl_vlan_pcp & VLAN_PCP_MASK );
4014
- }
4015
- }
4016
- }
4017
- if ( !( wildcards & OFPFW_DL_TYPE ) ) {
4018
- match->dl_type = ( ( packet_info * ) packet->user_data )->eth_type;
4019
- }
4020
- if ( match->dl_type == ETH_ETHTYPE_IPV4 ) {
4021
- if ( !( wildcards & OFPFW_NW_TOS ) ) {
4022
- match->nw_tos = ( ( packet_info * ) packet->user_data )->ipv4_tos;
4023
- if ( ( match->nw_tos & ~NW_TOS_MASK ) != 0 ) {
4024
- warn( "Invalid ipv4 tos ( change %#x to %#x )", match->nw_tos, match->nw_tos & NW_TOS_MASK );
4025
- match->nw_tos = ( uint8_t ) ( match->nw_tos & NW_TOS_MASK );
4026
- }
4027
- }
4028
- if ( !( wildcards & OFPFW_NW_PROTO ) ) {
4029
- match->nw_proto = ( ( packet_info * ) packet->user_data )->ipv4_protocol;
4030
- }
4031
- unsigned int nw_src_mask_len = ( wildcards & OFPFW_NW_SRC_MASK ) >> OFPFW_NW_SRC_SHIFT;
4032
- if ( nw_src_mask_len < 32 ) {
4033
- match->nw_src = ( ( packet_info * ) packet->user_data )->ipv4_saddr & ( 0xffffffff << nw_src_mask_len );
4034
- }
4035
- unsigned int nw_dst_mask_len = ( wildcards & OFPFW_NW_DST_MASK ) >> OFPFW_NW_DST_SHIFT;
4036
- if ( nw_dst_mask_len < 32 ) {
4037
- match->nw_dst = ( ( packet_info * ) packet->user_data )->ipv4_daddr & ( 0xffffffff << nw_dst_mask_len );
4038
- }
4039
-
4040
- switch ( match->nw_proto ) {
4041
- case IPPROTO_ICMP:
4042
- if ( !( wildcards & OFPFW_ICMP_TYPE ) ) {
4043
- match->icmp_type = ( ( packet_info * ) packet->user_data )->icmpv4_type;
4044
- }
4045
- if ( !( wildcards & OFPFW_ICMP_CODE ) ) {
4046
- match->icmp_code = ( ( packet_info * ) packet->user_data )->icmpv4_code;
4047
- }
4048
- break;
4049
- case IPPROTO_TCP:
4050
- if ( !( wildcards & OFPFW_TP_SRC ) ) {
4051
- match->tp_src = ( ( packet_info * ) packet->user_data )->tcp_src_port;
4052
- }
4053
- if ( !( wildcards & OFPFW_TP_DST ) ) {
4054
- match->tp_dst = ( ( packet_info * ) packet->user_data )->tcp_dst_port;
4055
- }
4056
- break;
4057
- case IPPROTO_UDP:
4058
- if ( !( wildcards & OFPFW_TP_SRC ) ) {
4059
- match->tp_src = ( ( packet_info * ) packet->user_data )->udp_src_port;
4060
- }
4061
- if ( !( wildcards & OFPFW_TP_DST ) ) {
4062
- match->tp_dst = ( ( packet_info * ) packet->user_data )->udp_dst_port;
4063
- }
4064
- break;
4065
-
4066
- default:
4067
- break;
4068
- }
4069
- }
4070
- if ( match->dl_type == ETH_ETHTYPE_ARP ) {
4071
- if ( !( wildcards & OFPFW_NW_PROTO ) ) {
4072
- match->nw_proto = ( uint8_t ) ( ( ( packet_info * ) packet->user_data )->arp_ar_op & ARP_OP_MASK );
4073
- }
4074
- unsigned int nw_src_mask_len = ( wildcards & OFPFW_NW_SRC_MASK ) >> OFPFW_NW_SRC_SHIFT;
4075
- if ( nw_src_mask_len < 32 ) {
4076
- match->nw_src = ( ( packet_info * ) packet->user_data )->arp_spa & ( 0xffffffff << nw_src_mask_len );
4077
- }
4078
- unsigned int nw_dst_mask_len = ( wildcards & OFPFW_NW_DST_MASK ) >> OFPFW_NW_DST_SHIFT;
4079
- if ( nw_dst_mask_len < 32 ) {
4080
- match->nw_dst = ( ( packet_info * ) packet->user_data )->arp_tpa & ( 0xffffffff << nw_dst_mask_len );
4081
- }
4082
- }
4083
- }
4084
-
4085
-
4086
- void
4087
- normalize_match( struct ofp_match *match ) {
4088
-
4089
- assert( match != NULL );
4090
-
4091
- char match_string[ 1024 ];
4092
- match_to_string( match, match_string, sizeof( match_string ) );
4093
- debug( "Normalizing match structure ( original match = [%s] ).", match_string );
4094
-
4095
- memset( match->pad1, 0, sizeof( match->pad1 ) );
4096
- memset( match->pad2, 0, sizeof( match->pad2 ) );
4097
-
4098
- match->wildcards &= OFPFW_ALL;
4099
-
4100
- if ( match->wildcards & OFPFW_IN_PORT ) {
4101
- match->in_port = 0;
4102
- }
4103
- if ( match->wildcards & OFPFW_DL_VLAN ) {
4104
- match->dl_vlan = 0;
4105
- }
4106
- else {
4107
- if ( match->dl_vlan == UINT16_MAX ) {
4108
- match->wildcards |= ( uint32_t ) OFPFW_DL_VLAN_PCP;
4109
- match->dl_vlan_pcp = 0;
4110
- }
4111
- else {
4112
- match->dl_vlan &= VLAN_VID_MASK;
4113
- }
4114
- }
4115
- if ( match->wildcards & OFPFW_DL_SRC ) {
4116
- memset( match->dl_src, 0, sizeof( match->dl_src ) );
4117
- }
4118
- if ( match->wildcards & OFPFW_DL_DST ) {
4119
- memset( match->dl_dst, 0, sizeof( match->dl_dst ) );
4120
- }
4121
- if ( match->wildcards & OFPFW_DL_TYPE ) {
4122
- match->dl_type = 0;
4123
- match->wildcards |= ( uint32_t ) OFPFW_NW_TOS;
4124
- match->wildcards |= ( uint32_t ) OFPFW_NW_PROTO;
4125
- match->wildcards |= ( uint32_t ) OFPFW_NW_SRC_MASK;
4126
- match->wildcards |= ( uint32_t ) OFPFW_NW_DST_MASK;
4127
- match->wildcards |= ( uint32_t ) OFPFW_TP_SRC;
4128
- match->wildcards |= ( uint32_t ) OFPFW_TP_DST;
4129
- match->nw_tos = 0;
4130
- match->nw_proto = 0;
4131
- match->nw_src = 0;
4132
- match->nw_dst = 0;
4133
- match->tp_src = 0;
4134
- match->tp_dst = 0;
4135
- }
4136
- else {
4137
- if ( match->dl_type == ETH_ETHTYPE_ARP ) {
4138
- match->wildcards |= ( uint32_t ) OFPFW_NW_TOS;
4139
- match->wildcards |= ( uint32_t ) OFPFW_TP_SRC;
4140
- match->wildcards |= ( uint32_t ) OFPFW_TP_DST;
4141
- match->nw_tos = 0;
4142
- match->tp_src = 0;
4143
- match->tp_dst = 0;
4144
- }
4145
- else if ( match->dl_type != ETH_ETHTYPE_IPV4 ) {
4146
- match->wildcards |= ( uint32_t ) OFPFW_NW_TOS;
4147
- match->wildcards |= ( uint32_t ) OFPFW_NW_PROTO;
4148
- match->wildcards |= ( uint32_t ) OFPFW_NW_SRC_MASK;
4149
- match->wildcards |= ( uint32_t ) OFPFW_NW_DST_MASK;
4150
- match->wildcards |= ( uint32_t ) OFPFW_TP_SRC;
4151
- match->wildcards |= ( uint32_t ) OFPFW_TP_DST;
4152
- match->nw_tos = 0;
4153
- match->nw_proto = 0;
4154
- match->nw_src = 0;
4155
- match->nw_dst = 0;
4156
- match->tp_src = 0;
4157
- match->tp_dst = 0;
4158
- }
4159
- }
4160
- if ( match->wildcards & OFPFW_NW_PROTO ) {
4161
- match->nw_proto = 0;
4162
- if ( match->dl_type != ETH_ETHTYPE_IPV4 ) {
4163
- match->wildcards |= ( uint32_t ) OFPFW_TP_SRC;
4164
- match->wildcards |= ( uint32_t ) OFPFW_TP_DST;
4165
- match->tp_src = 0;
4166
- match->tp_dst = 0;
4167
- }
4168
- }
4169
- else {
4170
- if ( match->dl_type == ETH_ETHTYPE_ARP ) {
4171
- match->nw_proto &= ARP_OP_MASK;
4172
- }
4173
- if ( match->dl_type == ETH_ETHTYPE_IPV4 &&
4174
- match->nw_proto != IPPROTO_TCP && match->nw_proto != IPPROTO_UDP && match->nw_proto != IPPROTO_ICMP ) {
4175
- match->wildcards |= ( uint32_t ) OFPFW_TP_SRC;
4176
- match->wildcards |= ( uint32_t ) OFPFW_TP_DST;
4177
- match->tp_src = 0;
4178
- match->tp_dst = 0;
4179
- }
4180
- }
4181
-
4182
- unsigned int nw_src_mask_len = ( match->wildcards & OFPFW_NW_SRC_MASK ) >> OFPFW_NW_SRC_SHIFT;
4183
- if ( nw_src_mask_len >= 32 ) {
4184
- match->wildcards &= ( uint32_t ) ~OFPFW_NW_SRC_MASK;
4185
- match->wildcards |= OFPFW_NW_SRC_ALL;
4186
- match->nw_src = 0;
4187
- }
4188
- else {
4189
- match->nw_src &= ( 0xffffffff << nw_src_mask_len );
4190
- }
4191
- unsigned int nw_dst_mask_len = ( match->wildcards & OFPFW_NW_DST_MASK ) >> OFPFW_NW_DST_SHIFT;
4192
- if ( nw_dst_mask_len >= 32 ) {
4193
- match->wildcards &= ( uint32_t ) ~OFPFW_NW_DST_MASK;
4194
- match->wildcards |= OFPFW_NW_DST_ALL;
4195
- match->nw_dst = 0;
4196
- }
4197
- else {
4198
- match->nw_dst &= ( 0xffffffff << nw_dst_mask_len );
4199
- }
4200
- if ( match->wildcards & OFPFW_TP_SRC ) {
4201
- match->tp_src = 0;
4202
- }
4203
- else {
4204
- if ( match->nw_proto == IPPROTO_ICMP ) {
4205
- match->tp_src &= ICMP_TYPE_MASK;
4206
- }
4207
- }
4208
- if ( match->wildcards & OFPFW_TP_DST ) {
4209
- match->tp_dst = 0;
4210
- }
4211
- else {
4212
- if ( match->nw_proto == IPPROTO_ICMP ) {
4213
- match->tp_dst &= ICMP_CODE_MASK;
4214
- }
4215
- }
4216
-
4217
- if ( match->wildcards & OFPFW_DL_VLAN_PCP ) {
4218
- match->dl_vlan_pcp = 0;
4219
- }
4220
- else {
4221
- match->dl_vlan_pcp &= VLAN_PCP_MASK;
4222
- }
4223
- if ( match->wildcards & OFPFW_NW_TOS ) {
4224
- match->nw_tos = 0;
4225
- }
4226
- else {
4227
- match->nw_tos &= NW_TOS_MASK;
4228
- }
4229
-
4230
- match_to_string( match, match_string, sizeof( match_string ) );
4231
- debug( "Normalization completed ( updated match = [%s] ).", match_string );
4232
- }
4233
-
4234
-
4235
- /*
4236
- * Local variables:
4237
- * c-basic-offset: 2
4238
- * indent-tabs-mode: nil
4239
- * End:
4240
- */