trema 0.2.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitmodules +3 -0
- data/.travis.yml +13 -0
- data/.yardopts +4 -0
- data/Gemfile +2 -3
- data/README.md +43 -97
- data/Rakefile +60 -4
- data/Rantfile +11 -10
- data/cruise.rb +4 -6
- data/features/example.packetin_filter_config.feature +10 -10
- data/features/example.switch_monitor.feature +14 -2
- data/features/step_definitions/kill_steps.rb +2 -2
- data/features/step_definitions/{off_steps.rb → killall_steps.rb} +2 -2
- data/features/step_definitions/misc_steps.rb +1 -1
- data/features/step_definitions/up_steps.rb +30 -0
- data/features/trema.feature +1 -0
- data/features/trema.run.feature +1 -0
- data/locale/README.ja.md +19 -0
- data/locale/ja/yard.po +3762 -0
- data/locale/yard.pot +3740 -0
- data/ruby/extconf.rb +4 -1
- data/ruby/trema/action-common.c +3 -17
- data/ruby/trema/action-common.h +3 -7
- data/ruby/trema/action.rb +33 -0
- data/ruby/trema/app.rb +1 -1
- data/ruby/trema/barrier-request.c +1 -0
- data/ruby/trema/command/run.rb +13 -9
- data/ruby/trema/command/usage.rb +1 -0
- data/ruby/trema/command/version.rb +1 -1
- data/ruby/trema/controller.c +133 -50
- data/ruby/trema/controller.rb +2 -2
- data/ruby/trema/desc-stats-reply.rb +77 -0
- data/ruby/trema/dsl/configuration.rb +3 -14
- data/ruby/trema/dsl/rswitch.rb +47 -0
- data/ruby/trema/dsl/runner.rb +4 -1
- data/ruby/trema/dsl/syntax.rb +11 -8
- data/ruby/trema/echo-reply.c +59 -45
- data/ruby/trema/echo-reply.h +1 -3
- data/ruby/trema/echo-request.c +49 -71
- data/ruby/trema/echo-request.h +0 -2
- data/ruby/trema/echo.c +99 -0
- data/ruby/trema/{action-enqueue.h → echo.h} +6 -7
- data/ruby/trema/enqueue.rb +87 -0
- data/ruby/trema/error.c +109 -104
- data/ruby/trema/error.h +0 -2
- data/ruby/trema/features-reply.c +89 -35
- data/ruby/trema/features-reply.h +0 -6
- data/ruby/trema/features-request.c +63 -37
- data/ruby/trema/features-request.h +0 -2
- data/ruby/trema/flow-mod.c +149 -0
- data/ruby/trema/{action-output.h → flow-mod.h} +6 -6
- data/ruby/trema/get-config-request.c +1 -0
- data/ruby/trema/hardware-switch.rb +88 -0
- data/ruby/trema/hello.c +55 -31
- data/ruby/trema/hello.h +0 -2
- data/ruby/trema/ip.rb +12 -2
- data/ruby/trema/logger.rb +29 -0
- data/ruby/trema/mac.rb +57 -36
- data/ruby/trema/match.c +7 -9
- data/ruby/trema/monkey-patch/integer/ranges.rb +0 -2
- data/ruby/trema/network-component.rb +1 -1
- data/ruby/trema/open-vswitch.rb +2 -2
- data/ruby/trema/openflow-switch.rb +3 -54
- data/ruby/trema/{packet_in.c → packet-in.c} +262 -175
- data/ruby/trema/{packet_in.h → packet-in.h} +0 -2
- data/ruby/trema/packet-queue.rb +4 -3
- data/ruby/trema/port-mod.c +8 -9
- data/ruby/trema/port-status-add.rb +60 -0
- data/ruby/trema/port-status-delete.rb +60 -0
- data/ruby/trema/port-status-modify.rb +60 -0
- data/ruby/trema/port-status.c +48 -15
- data/ruby/trema/port-status.h +6 -8
- data/ruby/trema/port.c +63 -8
- data/ruby/trema/queue-get-config-request.c +1 -0
- data/ruby/trema/ruby-switch.rb +62 -0
- data/ruby/trema/send-out-port.rb +97 -0
- data/ruby/trema/set-config.c +1 -0
- data/ruby/trema/set-eth-addr.rb +45 -0
- data/ruby/trema/set-eth-dst-addr.rb +54 -0
- data/ruby/trema/set-eth-src-addr.rb +54 -0
- data/ruby/trema/set-ip-addr.rb +47 -0
- data/ruby/trema/set-ip-dst-addr.rb +53 -0
- data/ruby/trema/set-ip-src-addr.rb +52 -0
- data/ruby/trema/set-ip-tos.rb +63 -0
- data/ruby/trema/set-transport-dst-port.rb +53 -0
- data/ruby/trema/set-transport-port.rb +52 -0
- data/ruby/trema/set-transport-src-port.rb +54 -0
- data/ruby/trema/set-vlan-priority.rb +65 -0
- data/ruby/trema/set-vlan-vid.rb +64 -0
- data/ruby/trema/shell/down.rb +1 -1
- data/ruby/trema/shell/link.rb +4 -4
- data/ruby/trema/shell/run.rb +8 -6
- data/ruby/trema/shell/up.rb +3 -3
- data/ruby/trema/stats-reply.c +27 -2
- data/ruby/trema/stats-request.c +64 -23
- data/ruby/trema/strip-vlan-header.rb +41 -0
- data/ruby/trema/switch.c +196 -0
- data/ruby/trema/{action-vendor.h → switch.h} +5 -7
- data/ruby/trema/switch.rb +28 -9
- data/ruby/trema/trema-ruby-utils.c +66 -0
- data/ruby/trema/{action-set-dl-src.h → trema-ruby-utils.h} +9 -11
- data/ruby/trema/trema.c +61 -61
- data/ruby/trema/vendor-action.rb +73 -0
- data/ruby/trema/vendor.c +121 -52
- data/ruby/trema/vendor.h +6 -10
- data/ruby/trema/version.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/support/action.rb +52 -0
- data/spec/support/mandatory-option.rb +56 -0
- data/spec/support/openflow-message.rb +91 -7
- data/spec/support/port-status.rb +38 -0
- data/spec/trema/controller_spec.rb +0 -26
- data/spec/trema/dsl/configuration_spec.rb +3 -3
- data/spec/trema/dsl/runner_spec.rb +12 -32
- data/spec/trema/dsl/syntax_spec.rb +2 -11
- data/spec/trema/echo-reply_spec.rb +49 -14
- data/spec/trema/echo-request_spec.rb +86 -34
- data/spec/trema/enqueue_spec.rb +76 -0
- data/spec/trema/error_spec.rb +43 -58
- data/spec/trema/features-reply_spec.rb +58 -24
- data/spec/trema/features-request_spec.rb +54 -28
- data/spec/trema/flow-mod_spec.rb +99 -0
- data/spec/trema/{openflow-switch_spec.rb → hardware-switch_spec.rb} +3 -3
- data/spec/trema/hello_spec.rb +28 -14
- data/spec/trema/ip_spec.rb +54 -0
- data/spec/trema/mac_spec.rb +49 -64
- data/spec/trema/match_spec.rb +1 -1
- data/spec/trema/open-vswitch_spec.rb +7 -7
- data/spec/trema/packet-in_spec.rb +73 -16
- data/spec/trema/port-status-add_spec.rb +32 -0
- data/spec/trema/port-status-delete_spec.rb +32 -0
- data/spec/trema/port-status-modify_spec.rb +71 -0
- data/spec/trema/port-status_spec.rb +5 -76
- data/spec/trema/{action-output_spec.rb → send-out-port_spec.rb} +20 -47
- data/spec/trema/set-eth-dst-addr_spec.rb +75 -0
- data/spec/trema/set-eth-src-addr_spec.rb +72 -0
- data/spec/trema/set-ip-dst-addr_spec.rb +58 -0
- data/spec/trema/set-ip-src-addr_spec.rb +58 -0
- data/spec/trema/set-ip-tos_spec.rb +65 -0
- data/spec/trema/set-transport-dst-port_spec.rb +65 -0
- data/spec/trema/set-transport-src-port_spec.rb +65 -0
- data/spec/trema/set-vlan-priority_spec.rb +65 -0
- data/spec/trema/set-vlan-vid_spec.rb +65 -0
- data/spec/trema/shell/vhost_spec.rb +4 -1
- data/spec/trema/shell/vswitch_spec.rb +11 -11
- data/spec/trema/stats-reply_spec.rb +59 -13
- data/spec/trema/stats-request_spec.rb +6 -0
- data/spec/trema/{action-strip-vlan_spec.rb → strip-vlan-header_spec.rb} +3 -17
- data/spec/trema/switch-daemon_spec.rb +39 -0
- data/spec/trema/vendor-action_spec.rb +81 -0
- data/spec/trema/vendor_spec.rb +76 -0
- data/spec/trema_spec.rb +56 -0
- data/src/examples/dumper/dumper.c +0 -8
- data/src/examples/dumper/dumper.rb +52 -52
- data/src/examples/hello_trema/hello_trema.c +0 -2
- data/src/examples/learning_switch/learning-switch.rb +3 -3
- data/src/examples/multi_learning_switch/multi-learning-switch.rb +3 -3
- data/src/examples/openflow_message/features-request.rb +3 -3
- data/src/examples/packetin_filter_config/utils.c +4 -4
- data/src/examples/repeater_hub/repeater-hub.rb +3 -3
- data/src/examples/switch_info/switch_info.rb +2 -2
- data/src/examples/switch_monitor/switch_monitor.c +1 -1
- data/src/examples/traffic_monitor/traffic-monitor.rb +3 -3
- data/src/lib/arp.h +4 -1
- data/src/lib/chibach.c +391 -0
- data/src/lib/chibach.h +71 -0
- data/src/lib/chibach_private.c +170 -0
- data/src/lib/chibach_private.h +52 -0
- data/src/lib/ether.c +2 -1
- data/src/lib/ether.h +0 -1
- data/src/lib/ipv4.h +13 -14
- data/{ruby/trema/action-set-nw-src.h → src/lib/ipv6.h} +13 -9
- data/src/lib/log.c +161 -58
- data/src/lib/log.h +11 -16
- data/src/lib/messenger.c +36 -1
- data/src/lib/messenger.h +1 -0
- data/src/lib/openflow_application_interface.c +128 -28
- data/src/lib/openflow_application_interface.h +31 -6
- data/src/lib/openflow_message.c +2 -1
- data/src/lib/openflow_service_interface.h +1 -0
- data/src/lib/openflow_switch_interface.c +1380 -0
- data/src/lib/openflow_switch_interface.h +264 -0
- data/src/lib/packet_info.c +94 -11
- data/src/lib/packet_info.h +22 -3
- data/src/lib/packet_parser.c +38 -2
- data/src/lib/secure_channel.c +498 -0
- data/{ruby/trema/vendor-request.h → src/lib/secure_channel.h} +11 -10
- data/src/lib/tcp.h +0 -3
- data/src/lib/trema.c +38 -5
- data/{ruby/trema/action-set-nw-dst.h → src/lib/trema.hpp} +17 -8
- data/src/lib/trema_wrapper.c +5 -0
- data/src/lib/trema_wrapper.h +4 -0
- data/src/lib/utility.c +93 -4
- data/src/lib/utility.h +1 -0
- data/src/lib/wrapper.c +30 -7
- data/src/lib/wrapper.h +2 -0
- data/src/switch_manager/ofpmsg_recv.c +44 -30
- data/src/switch_manager/ofpmsg_send.c +40 -1
- data/src/switch_manager/ofpmsg_send.h +2 -0
- data/src/switch_manager/switch.c +153 -8
- data/src/switch_manager/switch.h +1 -0
- data/src/switch_manager/switchinfo.h +5 -0
- data/src/tremashark/README +2 -2
- data/src/tremashark/plugin/packet-trema/packet-trema.c +1 -0
- data/trema +1 -1
- data/unittests/lib/log_test.c +158 -34
- data/unittests/lib/openflow_application_interface_test.c +252 -69
- data/unittests/lib/openflow_message_test.c +3 -1
- data/unittests/lib/packet_parser_test.c +60 -15
- data/unittests/lib/test_packets/icmp6_echo_rep.cap +0 -0
- data/unittests/lib/test_packets/icmp6_echo_req.cap +0 -0
- data/unittests/lib/trema_test.c +2 -0
- data/unittests/lib/utility_test.c +65 -2
- data/unittests/lib/wrapper_test.c +29 -0
- data/vendor/{README → README.md} +2 -12
- data/vendor/packet-openflow.diff +13 -0
- metadata +86 -53
- data/GPL2 +0 -339
- data/ruby/trema/action-enqueue.c +0 -161
- data/ruby/trema/action-output.c +0 -169
- data/ruby/trema/action-set-dl-dst.c +0 -131
- data/ruby/trema/action-set-dl-dst.h +0 -44
- data/ruby/trema/action-set-dl-src.c +0 -131
- data/ruby/trema/action-set-nw-dst.c +0 -135
- data/ruby/trema/action-set-nw-src.c +0 -140
- data/ruby/trema/action-set-nw-tos.c +0 -124
- data/ruby/trema/action-set-nw-tos.h +0 -42
- data/ruby/trema/action-set-tp-dst.c +0 -122
- data/ruby/trema/action-set-tp-dst.h +0 -42
- data/ruby/trema/action-set-tp-src.c +0 -124
- data/ruby/trema/action-set-tp-src.h +0 -42
- data/ruby/trema/action-set-vlan-pcp.c +0 -128
- data/ruby/trema/action-set-vlan-pcp.h +0 -42
- data/ruby/trema/action-set-vlan-vid.c +0 -125
- data/ruby/trema/action-set-vlan-vid.h +0 -42
- data/ruby/trema/action-strip-vlan.c +0 -81
- data/ruby/trema/action-strip-vlan.h +0 -42
- data/ruby/trema/action-vendor.c +0 -121
- data/ruby/trema/vendor-request.c +0 -193
- data/spec/trema/action-enqueue_spec.rb +0 -100
- data/spec/trema/action-set-dl-dst_spec.rb +0 -95
- data/spec/trema/action-set-dl-src_spec.rb +0 -92
- data/spec/trema/action-set-nw-dst_spec.rb +0 -96
- data/spec/trema/action-set-nw-src_spec.rb +0 -97
- data/spec/trema/action-set-nw-tos_spec.rb +0 -88
- data/spec/trema/action-set-tp-dst_spec.rb +0 -88
- data/spec/trema/action-set-tp-src_spec.rb +0 -88
- data/spec/trema/action-set-vlan-pcp_spec.rb +0 -91
- data/spec/trema/action-set-vlan-vid_spec.rb +0 -91
- data/spec/trema/action-vendor_spec.rb +0 -90
- data/spec/trema/vendor-request_spec.rb +0 -79
|
@@ -130,36 +130,38 @@ ofpmsg_recv_error( struct switch_info *sw_info, buffer *buf ) {
|
|
|
130
130
|
free_buffer( buf );
|
|
131
131
|
return 0;
|
|
132
132
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
if ( length >= offsetof( struct ofp_flow_mod, idle_timeout ) ) {
|
|
142
|
-
uint16_t command = ntohs( flow_mod->command );
|
|
143
|
-
switch ( command ) {
|
|
144
|
-
case OFPFC_ADD:
|
|
145
|
-
{
|
|
146
|
-
if ( entry != NULL ) {
|
|
147
|
-
delete_cookie_entry( entry );
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
error( "No cookie entry found ( cookie = %#" PRIx64 " ).", cookie );
|
|
133
|
+
if ( sw_info->cookie_translation ) {
|
|
134
|
+
cookie_entry_t *entry = lookup_cookie_entry_by_cookie( &cookie );
|
|
135
|
+
if ( entry != NULL ) {
|
|
136
|
+
flow_mod->cookie = htonll( entry->application.cookie );
|
|
137
|
+
if ( length >= offsetof( struct ofp_flow_mod, actions ) ) {
|
|
138
|
+
flow_mod->flags = htons( entry->application.flags );
|
|
151
139
|
}
|
|
152
140
|
}
|
|
153
|
-
break;
|
|
154
141
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
142
|
+
if ( length >= offsetof( struct ofp_flow_mod, idle_timeout ) ) {
|
|
143
|
+
uint16_t command = ntohs( flow_mod->command );
|
|
144
|
+
switch ( command ) {
|
|
145
|
+
case OFPFC_ADD:
|
|
146
|
+
{
|
|
147
|
+
if ( entry != NULL ) {
|
|
148
|
+
delete_cookie_entry( entry );
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
error( "No cookie entry found ( cookie = %#" PRIx64 " ).", cookie );
|
|
152
|
+
}
|
|
153
|
+
}
|
|
159
154
|
break;
|
|
160
155
|
|
|
161
|
-
|
|
162
|
-
|
|
156
|
+
case OFPFC_MODIFY:
|
|
157
|
+
case OFPFC_MODIFY_STRICT:
|
|
158
|
+
case OFPFC_DELETE:
|
|
159
|
+
case OFPFC_DELETE_STRICT:
|
|
160
|
+
break;
|
|
161
|
+
|
|
162
|
+
default:
|
|
163
|
+
error( "Undefined flow_mod command ( command = %#x ).", command );
|
|
164
|
+
}
|
|
163
165
|
}
|
|
164
166
|
}
|
|
165
167
|
}
|
|
@@ -190,9 +192,13 @@ int
|
|
|
190
192
|
ofpmsg_recv_echoreply( struct switch_info *sw_info, buffer *buf ) {
|
|
191
193
|
ofpmsg_debug( "Receive 'echo reply' from a switch." );
|
|
192
194
|
|
|
193
|
-
|
|
195
|
+
int ret = switch_event_recv_echoreply( sw_info, buf );
|
|
196
|
+
if ( ret < 0 ) {
|
|
197
|
+
free_buffer( buf );
|
|
198
|
+
return ret;
|
|
199
|
+
}
|
|
194
200
|
|
|
195
|
-
|
|
201
|
+
send_transaction_reply( sw_info, buf );
|
|
196
202
|
|
|
197
203
|
return 0;
|
|
198
204
|
}
|
|
@@ -274,14 +280,22 @@ ofpmsg_recv_flowremoved( struct switch_info *sw_info, buffer *buf ) {
|
|
|
274
280
|
return 0;
|
|
275
281
|
}
|
|
276
282
|
|
|
283
|
+
if ( !sw_info->cookie_translation ) {
|
|
284
|
+
service_send_to_application( sw_info->state_service_name_list, MESSENGER_OPENFLOW_MESSAGE,
|
|
285
|
+
&sw_info->datapath_id, buf );
|
|
286
|
+
free_buffer( buf );
|
|
287
|
+
return 0;
|
|
288
|
+
}
|
|
289
|
+
|
|
277
290
|
entry = lookup_cookie_entry_by_cookie( &cookie );
|
|
278
291
|
if ( entry == NULL ) {
|
|
279
292
|
error( "No cookie entry found ( cookie = %#" PRIx64 " ).", cookie );
|
|
280
293
|
free_buffer( buf );
|
|
281
294
|
return 0;
|
|
282
295
|
}
|
|
283
|
-
|
|
284
|
-
|
|
296
|
+
|
|
297
|
+
debug( "Cookie found ( cookie = %#" PRIx64 ", application = [ cookie = %#" PRIx64
|
|
298
|
+
", service name = %s, flags = %#x ], reference_count = %d, expire_at = %u ).",
|
|
285
299
|
cookie, entry->application.cookie, entry->application.service_name, entry->application.flags,
|
|
286
300
|
entry->reference_count, entry->expire_at );
|
|
287
301
|
|
|
@@ -319,7 +333,7 @@ ofpmsg_recv_statsreply( struct switch_info *sw_info, buffer *buf ) {
|
|
|
319
333
|
|
|
320
334
|
ofpmsg_debug( "Receive 'statistics reply' from a switch." );
|
|
321
335
|
|
|
322
|
-
if ( type == OFPST_FLOW ) {
|
|
336
|
+
if ( type == OFPST_FLOW && sw_info->cookie_translation ) {
|
|
323
337
|
size_t body_offset = offsetof( struct ofp_stats_reply, body );
|
|
324
338
|
int body_length = ntohs( stats_reply->header.length ) - ( int ) body_offset;
|
|
325
339
|
struct ofp_flow_stats *flow_stats = ( void * ) ( ( char * ) stats_reply + body_offset );
|
|
@@ -46,6 +46,23 @@ ofpmsg_send_hello( struct switch_info *sw_info ) {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
|
|
49
|
+
int
|
|
50
|
+
ofpmsg_send_echorequest( struct switch_info *sw_info, uint32_t xid, buffer *body ) {
|
|
51
|
+
int ret;
|
|
52
|
+
buffer *buf;
|
|
53
|
+
|
|
54
|
+
buf = create_echo_request( xid, body );
|
|
55
|
+
free_buffer( body );
|
|
56
|
+
|
|
57
|
+
ret = send_to_secure_channel( sw_info, buf );
|
|
58
|
+
if ( ret == 0 ) {
|
|
59
|
+
debug( "Send 'echo request' to a switch %#" PRIx64 ".", sw_info->datapath_id );
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return ret;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
49
66
|
int
|
|
50
67
|
ofpmsg_send_echoreply( struct switch_info *sw_info, uint32_t xid, buffer *body ) {
|
|
51
68
|
int ret;
|
|
@@ -187,7 +204,7 @@ ofpmsg_send( struct switch_info *sw_info, buffer *buf, char *service_name ) {
|
|
|
187
204
|
new_xid = insert_xid_entry( ntohl( ofp_header->xid ), service_name );
|
|
188
205
|
ofp_header->xid = htonl( new_xid );
|
|
189
206
|
|
|
190
|
-
if ( ofp_header->type == OFPT_FLOW_MOD ) {
|
|
207
|
+
if ( ofp_header->type == OFPT_FLOW_MOD && sw_info->cookie_translation ) {
|
|
191
208
|
ret = update_flowmod_cookie( buf, service_name );
|
|
192
209
|
if ( ret < 0 ) {
|
|
193
210
|
error( "Failed to update cookie value ( ret = %d ).", ret );
|
|
@@ -227,6 +244,28 @@ ofpmsg_send_delete_all_flows( struct switch_info *sw_info ) {
|
|
|
227
244
|
}
|
|
228
245
|
|
|
229
246
|
|
|
247
|
+
int
|
|
248
|
+
ofpmsg_send_deny_all( struct switch_info *sw_info ) {
|
|
249
|
+
int ret;
|
|
250
|
+
struct ofp_match match;
|
|
251
|
+
buffer *buf;
|
|
252
|
+
|
|
253
|
+
memset( &match, 0, sizeof( match ) );
|
|
254
|
+
match.wildcards = OFPFW_ALL;
|
|
255
|
+
const uint16_t timeout = 10;
|
|
256
|
+
|
|
257
|
+
buf = create_flow_mod( generate_xid(), match, RESERVED_COOKIE,
|
|
258
|
+
OFPFC_ADD, 0, timeout, UINT16_MAX, UINT32_MAX, OFPP_NONE, 0, NULL );
|
|
259
|
+
|
|
260
|
+
ret = send_to_secure_channel( sw_info, buf );
|
|
261
|
+
if ( ret == 0 ) {
|
|
262
|
+
debug( "Send 'flow mod (deny all)' to a switch %#" PRIx64 ".", sw_info->datapath_id );
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return ret;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
|
|
230
269
|
/*
|
|
231
270
|
* Local variables:
|
|
232
271
|
* c-basic-offset: 2
|
|
@@ -30,12 +30,14 @@
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
int ofpmsg_send_hello( struct switch_info *sw_info );
|
|
33
|
+
int ofpmsg_send_echorequest( struct switch_info *sw_info, uint32_t xid, buffer *body );
|
|
33
34
|
int ofpmsg_send_echoreply( struct switch_info *sw_info, uint32_t xid, buffer *body );
|
|
34
35
|
int ofpmsg_send_featuresrequest( struct switch_info *sw_info );
|
|
35
36
|
int ofpmsg_send_setconfig( struct switch_info *sw_info );
|
|
36
37
|
int ofpmsg_send_error_msg( struct switch_info *sw_info, uint16_t type, uint16_t code, buffer *data );
|
|
37
38
|
int ofpmsg_send( struct switch_info *sw_info, buffer *buf, char *service_name );
|
|
38
39
|
int ofpmsg_send_delete_all_flows( struct switch_info *sw_info );
|
|
40
|
+
int ofpmsg_send_deny_all( struct switch_info *sw_info );
|
|
39
41
|
|
|
40
42
|
|
|
41
43
|
#endif // OFPMSG_SEND_H
|
data/src/switch_manager/switch.c
CHANGED
|
@@ -42,13 +42,29 @@
|
|
|
42
42
|
#include "xid_table.h"
|
|
43
43
|
|
|
44
44
|
|
|
45
|
+
#define SUB_TIMESPEC( _a, _b, _return ) \
|
|
46
|
+
do { \
|
|
47
|
+
( _return )->tv_sec = ( _a )->tv_sec - ( _b )->tv_sec; \
|
|
48
|
+
( _return )->tv_nsec = ( _a )->tv_nsec - ( _b )->tv_nsec; \
|
|
49
|
+
if ( ( _return )->tv_nsec < 0 ) { \
|
|
50
|
+
( _return )->tv_sec--; \
|
|
51
|
+
( _return )->tv_nsec += 1000000000; \
|
|
52
|
+
} \
|
|
53
|
+
} \
|
|
54
|
+
while ( 0 )
|
|
55
|
+
|
|
56
|
+
|
|
45
57
|
enum long_options_val {
|
|
46
58
|
NO_FLOW_CLEANUP_LONG_OPTION_VALUE = 1,
|
|
59
|
+
NO_COOKIE_TRANSLATION_LONG_OPTION_VALUE = 2,
|
|
60
|
+
NO_PACKET_IN_LONG_OPTION_VALUE = 3,
|
|
47
61
|
};
|
|
48
62
|
|
|
49
63
|
static struct option long_options[] = {
|
|
50
64
|
{ "socket", 1, NULL, 's' },
|
|
51
65
|
{ "no-flow-cleanup", 0, NULL, NO_FLOW_CLEANUP_LONG_OPTION_VALUE },
|
|
66
|
+
{ "no-cookie-translation", 0, NULL, NO_COOKIE_TRANSLATION_LONG_OPTION_VALUE },
|
|
67
|
+
{ "no-packet_in", 0, NULL, NO_PACKET_IN_LONG_OPTION_VALUE },
|
|
52
68
|
{ NULL, 0, NULL, 0 },
|
|
53
69
|
};
|
|
54
70
|
|
|
@@ -58,9 +74,16 @@ static char short_options[] = "s:";
|
|
|
58
74
|
struct switch_info switch_info;
|
|
59
75
|
|
|
60
76
|
static const time_t COOKIE_TABLE_AGING_INTERVAL = 3600;
|
|
77
|
+
static const time_t ECHO_REQUEST_INTERVAL = 60;
|
|
78
|
+
static const time_t ECHO_REPLY_TIMEOUT = 2;
|
|
61
79
|
|
|
62
80
|
static bool age_cookie_table_enabled = false;
|
|
63
81
|
|
|
82
|
+
typedef struct {
|
|
83
|
+
uint64_t datapath_id;
|
|
84
|
+
uint32_t sec;
|
|
85
|
+
uint32_t nsec;
|
|
86
|
+
} echo_body;
|
|
64
87
|
|
|
65
88
|
void
|
|
66
89
|
usage() {
|
|
@@ -71,7 +94,9 @@ usage() {
|
|
|
71
94
|
" -s, --socket=fd secure channnel socket\n"
|
|
72
95
|
" -n, --name=SERVICE_NAME service name\n"
|
|
73
96
|
" -l, --logging_level=LEVEL set logging level\n"
|
|
74
|
-
" --no-flow-cleanup do not cleanup flows on
|
|
97
|
+
" --no-flow-cleanup do not cleanup flows on startup\n"
|
|
98
|
+
" --no-cookie-translation do not translate cookie values\n"
|
|
99
|
+
" --no-packet_in do not allow packet-ins on startup\n"
|
|
75
100
|
" -h, --help display this help and exit\n"
|
|
76
101
|
"\n"
|
|
77
102
|
"DESTINATION-RULE:\n"
|
|
@@ -109,6 +134,8 @@ option_parser( int argc, char *argv[] ) {
|
|
|
109
134
|
|
|
110
135
|
switch_info.secure_channel_fd = 0; // stdin
|
|
111
136
|
switch_info.flow_cleanup = true;
|
|
137
|
+
switch_info.cookie_translation = true;
|
|
138
|
+
switch_info.deny_packet_in_on_startup = false;
|
|
112
139
|
while ( ( c = getopt_long( argc, argv, short_options, long_options, NULL ) ) != -1 ) {
|
|
113
140
|
switch ( c ) {
|
|
114
141
|
case 's':
|
|
@@ -119,6 +146,14 @@ option_parser( int argc, char *argv[] ) {
|
|
|
119
146
|
switch_info.flow_cleanup = false;
|
|
120
147
|
break;
|
|
121
148
|
|
|
149
|
+
case NO_COOKIE_TRANSLATION_LONG_OPTION_VALUE:
|
|
150
|
+
switch_info.cookie_translation = false;
|
|
151
|
+
break;
|
|
152
|
+
|
|
153
|
+
case NO_PACKET_IN_LONG_OPTION_VALUE:
|
|
154
|
+
switch_info.deny_packet_in_on_startup = true;
|
|
155
|
+
break;
|
|
156
|
+
|
|
122
157
|
default:
|
|
123
158
|
usage();
|
|
124
159
|
exit( EXIT_SUCCESS );
|
|
@@ -259,6 +294,13 @@ switch_event_recv_hello( struct switch_info *sw_info ) {
|
|
|
259
294
|
// cancel to hello_wait-timeout timer
|
|
260
295
|
switch_unset_timeout( switch_event_timeout_hello, NULL );
|
|
261
296
|
|
|
297
|
+
if ( sw_info->deny_packet_in_on_startup ) {
|
|
298
|
+
ret = ofpmsg_send_deny_all( sw_info );
|
|
299
|
+
if ( ret < 0 ) {
|
|
300
|
+
return ret;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
262
304
|
ret = ofpmsg_send_featuresrequest( sw_info );
|
|
263
305
|
if ( ret < 0 ) {
|
|
264
306
|
return ret;
|
|
@@ -273,6 +315,66 @@ switch_event_recv_hello( struct switch_info *sw_info ) {
|
|
|
273
315
|
}
|
|
274
316
|
|
|
275
317
|
|
|
318
|
+
static void
|
|
319
|
+
echo_reply_timeout( void *user_data ) {
|
|
320
|
+
UNUSED( user_data );
|
|
321
|
+
|
|
322
|
+
error( "Echo request timeout ( datapath id %#" PRIx64 ").", switch_info.datapath_id );
|
|
323
|
+
switch_event_disconnected( &switch_info );
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
int
|
|
328
|
+
switch_event_recv_echoreply( struct switch_info *sw_info, buffer *buf ) {
|
|
329
|
+
if ( buf->length != sizeof( struct ofp_header ) + sizeof( echo_body ) ) {
|
|
330
|
+
return 0;
|
|
331
|
+
}
|
|
332
|
+
struct ofp_header *header = buf->data;
|
|
333
|
+
if ( ntohl( header->xid ) != sw_info->echo_request_xid ) {
|
|
334
|
+
return 0;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
echo_body *body = ( echo_body * ) ( header + 1 );
|
|
338
|
+
if ( ntohll( body->datapath_id ) != sw_info->datapath_id ) {
|
|
339
|
+
return 0;
|
|
340
|
+
}
|
|
341
|
+
switch_unset_timeout( echo_reply_timeout, NULL );
|
|
342
|
+
struct timespec now, tim;
|
|
343
|
+
clock_gettime( CLOCK_MONOTONIC, &now );
|
|
344
|
+
tim.tv_sec = ( time_t ) ntohl( body->sec );
|
|
345
|
+
tim.tv_nsec = ( long ) ntohl( body->nsec );
|
|
346
|
+
|
|
347
|
+
SUB_TIMESPEC( &now, &tim, &tim );
|
|
348
|
+
|
|
349
|
+
info( "echo round-trip time %u.%09u.", ( uint32_t ) tim.tv_sec, ( uint32_t ) tim.tv_nsec );
|
|
350
|
+
|
|
351
|
+
return 0;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
static void
|
|
356
|
+
echo_request_interval( void *user_data ) {
|
|
357
|
+
struct switch_info *sw_info = user_data;
|
|
358
|
+
|
|
359
|
+
buffer *buf = alloc_buffer();
|
|
360
|
+
echo_body *body = append_back_buffer( buf, sizeof( echo_body ) );
|
|
361
|
+
body->datapath_id = htonll( switch_info.datapath_id );
|
|
362
|
+
struct timespec now;
|
|
363
|
+
clock_gettime( CLOCK_MONOTONIC, &now );
|
|
364
|
+
body->sec = htonl( ( uint32_t ) now.tv_sec );
|
|
365
|
+
body->nsec = htonl( ( uint32_t ) now.tv_nsec );
|
|
366
|
+
sw_info->echo_request_xid = generate_xid();
|
|
367
|
+
|
|
368
|
+
int err = ofpmsg_send_echorequest( sw_info, sw_info->echo_request_xid, buf );
|
|
369
|
+
if ( err < 0 ) {
|
|
370
|
+
switch_event_disconnected( &switch_info );
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
switch_set_timeout( ECHO_REPLY_TIMEOUT, echo_reply_timeout, NULL );
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
|
|
276
378
|
int
|
|
277
379
|
switch_event_recv_featuresreply( struct switch_info *sw_info, uint64_t *dpid ) {
|
|
278
380
|
int ret;
|
|
@@ -323,6 +425,7 @@ switch_event_recv_featuresreply( struct switch_info *sw_info, uint64_t *dpid ) {
|
|
|
323
425
|
return ret;
|
|
324
426
|
}
|
|
325
427
|
}
|
|
428
|
+
add_periodic_event_callback( ECHO_REQUEST_INTERVAL, echo_request_interval, sw_info );
|
|
326
429
|
break;
|
|
327
430
|
|
|
328
431
|
case SWITCH_STATE_COMPLETED:
|
|
@@ -342,8 +445,14 @@ switch_event_recv_featuresreply( struct switch_info *sw_info, uint64_t *dpid ) {
|
|
|
342
445
|
|
|
343
446
|
int
|
|
344
447
|
switch_event_disconnected( struct switch_info *sw_info ) {
|
|
448
|
+
int old_state = sw_info->state;
|
|
449
|
+
|
|
345
450
|
sw_info->state = SWITCH_STATE_DISCONNECTED;
|
|
346
451
|
|
|
452
|
+
if ( old_state == SWITCH_STATE_COMPLETED ) {
|
|
453
|
+
delete_timer_event( echo_request_interval, sw_info );
|
|
454
|
+
}
|
|
455
|
+
|
|
347
456
|
if ( sw_info->fragment_buf != NULL ) {
|
|
348
457
|
free_buffer( sw_info->fragment_buf );
|
|
349
458
|
sw_info->fragment_buf = NULL;
|
|
@@ -368,13 +477,16 @@ switch_event_disconnected( struct switch_info *sw_info ) {
|
|
|
368
477
|
sw_info->secure_channel_fd = -1;
|
|
369
478
|
}
|
|
370
479
|
|
|
371
|
-
|
|
372
|
-
|
|
480
|
+
if ( old_state != SWITCH_STATE_COMPLETED ) {
|
|
481
|
+
service_send_state( sw_info, &sw_info->datapath_id, MESSENGER_OPENFLOW_FAILD_TO_CONNECT );
|
|
482
|
+
}
|
|
483
|
+
else {
|
|
484
|
+
// send secure channle disconnect state to application
|
|
485
|
+
service_send_state( sw_info, &sw_info->datapath_id, MESSENGER_OPENFLOW_DISCONNECTED );
|
|
486
|
+
}
|
|
373
487
|
flush_messenger();
|
|
374
|
-
debug( "send disconnected state" );
|
|
375
488
|
|
|
376
|
-
|
|
377
|
-
stop_messenger();
|
|
489
|
+
stop_trema();
|
|
378
490
|
|
|
379
491
|
return 0;
|
|
380
492
|
}
|
|
@@ -426,10 +538,16 @@ management_recv( uint16_t tag, void *data, size_t data_len ) {
|
|
|
426
538
|
break;
|
|
427
539
|
|
|
428
540
|
case DUMP_COOKIE_TABLE:
|
|
541
|
+
if ( !switch_info.cookie_translation ) {
|
|
542
|
+
break;
|
|
543
|
+
}
|
|
429
544
|
dump_cookie_table();
|
|
430
545
|
break;
|
|
431
546
|
|
|
432
547
|
case TOGGLE_COOKIE_AGING:
|
|
548
|
+
if ( !switch_info.cookie_translation ) {
|
|
549
|
+
break;
|
|
550
|
+
}
|
|
433
551
|
if ( age_cookie_table_enabled ) {
|
|
434
552
|
delete_timer_event( age_cookie_table, NULL );
|
|
435
553
|
age_cookie_table_enabled = false;
|
|
@@ -446,6 +564,22 @@ management_recv( uint16_t tag, void *data, size_t data_len ) {
|
|
|
446
564
|
}
|
|
447
565
|
|
|
448
566
|
|
|
567
|
+
static void
|
|
568
|
+
stop_switch_daemon( void ) {
|
|
569
|
+
switch_event_disconnected( &switch_info );
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
static void
|
|
574
|
+
handle_sigterm( int signum ) {
|
|
575
|
+
UNUSED( signum );
|
|
576
|
+
|
|
577
|
+
if ( !set_external_callback( stop_switch_daemon ) ) {
|
|
578
|
+
stop_trema();
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
|
|
449
583
|
int
|
|
450
584
|
main( int argc, char *argv[] ) {
|
|
451
585
|
int ret;
|
|
@@ -485,6 +619,12 @@ main( int argc, char *argv[] ) {
|
|
|
485
619
|
}
|
|
486
620
|
}
|
|
487
621
|
|
|
622
|
+
struct sigaction signal_exit;
|
|
623
|
+
memset( &signal_exit, 0, sizeof( struct sigaction ) );
|
|
624
|
+
signal_exit.sa_handler = handle_sigterm;
|
|
625
|
+
sigaction( SIGINT, &signal_exit, NULL );
|
|
626
|
+
sigaction( SIGTERM, &signal_exit, NULL );
|
|
627
|
+
|
|
488
628
|
fcntl( switch_info.secure_channel_fd, F_SETFL, O_NONBLOCK );
|
|
489
629
|
|
|
490
630
|
set_fd_handler( switch_info.secure_channel_fd, secure_channel_read, NULL, secure_channel_write, NULL );
|
|
@@ -499,9 +639,12 @@ main( int argc, char *argv[] ) {
|
|
|
499
639
|
switch_info.send_queue = create_message_queue();
|
|
500
640
|
switch_info.recv_queue = create_message_queue();
|
|
501
641
|
switch_info.running_timer = false;
|
|
642
|
+
switch_info.echo_request_xid = 0;
|
|
502
643
|
|
|
503
644
|
init_xid_table();
|
|
504
|
-
|
|
645
|
+
if ( switch_info.cookie_translation ) {
|
|
646
|
+
init_cookie_table();
|
|
647
|
+
}
|
|
505
648
|
|
|
506
649
|
add_message_received_callback( get_trema_name(), service_recv );
|
|
507
650
|
|
|
@@ -520,7 +663,9 @@ main( int argc, char *argv[] ) {
|
|
|
520
663
|
start_trema();
|
|
521
664
|
|
|
522
665
|
finalize_xid_table();
|
|
523
|
-
|
|
666
|
+
if ( switch_info.cookie_translation ) {
|
|
667
|
+
finalize_cookie_table();
|
|
668
|
+
}
|
|
524
669
|
|
|
525
670
|
if ( switch_info.secure_channel_fd >= 0 ) {
|
|
526
671
|
delete_fd_handler( switch_info.secure_channel_fd );
|