trema 0.4.7 → 0.4.8

Sign up to get free protection for your applications and to get access to all the features.
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
- */