trema 0.3.16 → 0.3.17
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.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.rvmrc +52 -0
- data/.travis.yml +3 -0
- data/Gemfile +1 -1
- data/Rakefile +259 -1
- data/Rantfile +79 -216
- data/features/.nav +12 -0
- data/features/dsl/switch_port_specifier.feature +15 -0
- data/features/examples/switch-event/C-add_forward_entry.feature +130 -0
- data/features/examples/switch-event/C-delete_forward_entry.feature +97 -0
- data/features/examples/switch-event/C-dump_forward_entries.feature +80 -0
- data/features/examples/switch-event/C-set_forward_entries.feature +85 -0
- data/features/examples/switch-event/README.md +40 -0
- data/features/examples/switch-event/add_forward_entry.feature +142 -0
- data/features/examples/switch-event/delete_forward_entry.feature +142 -0
- data/features/examples/switch-event/dump_forward_entries.feature +91 -0
- data/features/examples/switch-event/set_forward_entries.feature +90 -0
- data/features/support/hooks.rb +1 -0
- data/ruby/rake/c/dependency.rb +42 -0
- data/ruby/rake/c/library-task.rb +142 -0
- data/ruby/rake/c/shared-library-task.rb +38 -0
- data/ruby/rake/c/static-library-task.rb +32 -0
- data/ruby/trema/path.rb +1 -0
- data/ruby/trema/switch-event.c +647 -0
- data/{src/switch_manager/management_interface.h → ruby/trema/switch-event.h} +7 -21
- data/ruby/trema/trema.c +2 -0
- data/ruby/trema/version.rb +1 -1
- data/spec/spec_helper.rb +26 -2
- data/src/examples/switch_event_config/.gitignore +7 -0
- data/src/examples/switch_event_config/add_forward_entry.c +227 -0
- data/src/examples/switch_event_config/delete_forward_entry.c +226 -0
- data/src/examples/switch_event_config/dump_forward_entries.c +190 -0
- data/src/examples/switch_event_config/set_forward_entries.c +210 -0
- data/src/lib/event_forward_interface.c +783 -0
- data/src/lib/event_forward_interface.h +138 -0
- data/src/lib/trema.h +1 -0
- data/src/lib/utility.c +13 -1
- data/src/lib/utility.h +3 -0
- data/src/switch_manager/event_forward_entry_manipulation.c +120 -0
- data/src/switch_manager/event_forward_entry_manipulation.h +31 -0
- data/src/switch_manager/secure_channel_listener.c +23 -3
- data/src/switch_manager/switch.c +99 -29
- data/src/switch_manager/switch_manager.c +176 -3
- data/src/switch_manager/switch_manager.h +4 -0
- data/src/switch_manager/switch_option.c +30 -0
- data/src/switch_manager/switch_option.h +41 -0
- data/trema.gemspec +2 -1
- data/unittests/lib/event_forward_interface_test.c +1646 -0
- data/unittests/lib/utility_test.c +23 -1
- metadata +48 -10
@@ -0,0 +1,138 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (C) 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
|
+
#ifndef EVENT_FORWARD_INTERFACE_H_
|
19
|
+
#define EVENT_FORWARD_INTERFACE_H_
|
20
|
+
|
21
|
+
|
22
|
+
#include "buffer.h"
|
23
|
+
#include "linked_list.h"
|
24
|
+
|
25
|
+
// management interface application_ids
|
26
|
+
enum switch_management_command {
|
27
|
+
// switch only
|
28
|
+
DUMP_XID_TABLE = 0,
|
29
|
+
DUMP_COOKIE_TABLE,
|
30
|
+
TOGGLE_COOKIE_AGING,
|
31
|
+
|
32
|
+
// switch manager/daemon
|
33
|
+
EVENT_FORWARD_ENTRY_ADD,
|
34
|
+
EVENT_FORWARD_ENTRY_DELETE,
|
35
|
+
EVENT_FORWARD_ENTRY_DUMP,
|
36
|
+
EVENT_FORWARD_ENTRY_SET,
|
37
|
+
|
38
|
+
// switch manager only
|
39
|
+
EFI_GET_SWLIST,
|
40
|
+
};
|
41
|
+
|
42
|
+
enum efi_event_type {
|
43
|
+
EVENT_FORWARD_TYPE_VENDOR = 0,
|
44
|
+
EVENT_FORWARD_TYPE_PACKET_IN,
|
45
|
+
EVENT_FORWARD_TYPE_PORT_STATUS,
|
46
|
+
EVENT_FORWARD_TYPE_STATE_NOTIFY
|
47
|
+
};
|
48
|
+
|
49
|
+
enum efi_result {
|
50
|
+
EFI_OPERATION_SUCCEEDED = 0,
|
51
|
+
EFI_OPERATION_FAILED,
|
52
|
+
};
|
53
|
+
|
54
|
+
// messenger message data structure
|
55
|
+
typedef struct {
|
56
|
+
// enum efi_event_type
|
57
|
+
uint8_t type;
|
58
|
+
uint8_t pad[3];
|
59
|
+
// Number of element in service_list. 0 for dump, 1 for add/delete, N for set operation.
|
60
|
+
uint32_t n_services;
|
61
|
+
// e.g. "service1\0service2\0"
|
62
|
+
char service_list[0];
|
63
|
+
} __attribute__( ( packed ) ) event_forward_operation_request;
|
64
|
+
|
65
|
+
typedef struct {
|
66
|
+
// enum efi_event_type
|
67
|
+
uint8_t type;
|
68
|
+
// enum efi_result
|
69
|
+
uint8_t result;
|
70
|
+
uint8_t pad[2];
|
71
|
+
uint32_t n_services;
|
72
|
+
// service list after operation
|
73
|
+
char service_list[0];
|
74
|
+
} __attribute__( ( packed ) ) event_forward_operation_reply;
|
75
|
+
|
76
|
+
|
77
|
+
// struct for user API
|
78
|
+
typedef struct {
|
79
|
+
enum efi_result result;
|
80
|
+
uint32_t n_services;
|
81
|
+
// service list after operation.
|
82
|
+
const char **services;
|
83
|
+
} event_forward_operation_result;
|
84
|
+
|
85
|
+
|
86
|
+
// High level API callback function signature
|
87
|
+
typedef void ( *event_forward_entry_to_all_callback )(
|
88
|
+
enum efi_result result,
|
89
|
+
void *user_data
|
90
|
+
);
|
91
|
+
|
92
|
+
|
93
|
+
// Low level API callback function signature
|
94
|
+
typedef void ( *event_forward_entry_operation_callback )(
|
95
|
+
event_forward_operation_result result,
|
96
|
+
void *user_data
|
97
|
+
);
|
98
|
+
|
99
|
+
|
100
|
+
typedef void ( *switch_list_request_callback )(
|
101
|
+
// NULL if failed
|
102
|
+
uint64_t* dpids,
|
103
|
+
size_t n_dpids,
|
104
|
+
void *user_data
|
105
|
+
);
|
106
|
+
|
107
|
+
|
108
|
+
// setup/teardown messenger channel
|
109
|
+
bool init_event_forward_interface( void );
|
110
|
+
bool finalize_event_forward_interface( void );
|
111
|
+
|
112
|
+
|
113
|
+
// High level API (calls Low level API for switch manager and existing switch daemons)
|
114
|
+
bool add_event_forward_entry_to_all_switches( enum efi_event_type type, const char* service_name, event_forward_entry_to_all_callback callback, void* user_data );
|
115
|
+
bool delete_event_forward_entry_to_all_switches( enum efi_event_type type, const char* service_name, event_forward_entry_to_all_callback callback, void* user_data );
|
116
|
+
|
117
|
+
|
118
|
+
// Low level API for switch manager
|
119
|
+
bool set_switch_manager_event_forward_entries( enum efi_event_type type, list_element* service_list, event_forward_entry_operation_callback callback, void* user_data );
|
120
|
+
bool add_switch_manager_event_forward_entry( enum efi_event_type type, const char* service_name, event_forward_entry_operation_callback callback, void* user_data );
|
121
|
+
bool delete_switch_manager_event_forward_entry( enum efi_event_type type, const char* service_name, event_forward_entry_operation_callback callback, void* user_data );
|
122
|
+
bool dump_switch_manager_event_forward_entries( enum efi_event_type type, event_forward_entry_operation_callback callback, void* user_data );
|
123
|
+
|
124
|
+
|
125
|
+
// Low level API for switch daemon
|
126
|
+
bool set_switch_event_forward_entries( uint64_t dpid, enum efi_event_type type, list_element* service_list, event_forward_entry_operation_callback callback, void* user_data );
|
127
|
+
bool add_switch_event_forward_entry( uint64_t dpid, enum efi_event_type type, const char* service_name, event_forward_entry_operation_callback callback, void* user_data );
|
128
|
+
bool delete_switch_event_forward_entry( uint64_t dpid, enum efi_event_type type, const char* service_name, event_forward_entry_operation_callback callback, void* user_data );
|
129
|
+
bool dump_switch_event_forward_entries( uint64_t dpid, enum efi_event_type type, event_forward_entry_operation_callback callback, void* user_data );
|
130
|
+
|
131
|
+
|
132
|
+
// internal utilities
|
133
|
+
buffer* create_event_forward_operation_request( buffer* buf, enum efi_event_type, list_element* service_list );
|
134
|
+
buffer* create_event_forward_operation_reply( enum efi_event_type, enum efi_result, list_element* service_list );
|
135
|
+
|
136
|
+
bool send_efi_switch_list_request( switch_list_request_callback callback, void* user_data );
|
137
|
+
|
138
|
+
#endif /* EVENT_FORWARD_INTERFACE_H_ */
|
data/src/lib/trema.h
CHANGED
data/src/lib/utility.c
CHANGED
@@ -31,7 +31,7 @@
|
|
31
31
|
#include "log.h"
|
32
32
|
#include "trema_wrapper.h"
|
33
33
|
#include "utility.h"
|
34
|
-
|
34
|
+
#include "wrapper.h"
|
35
35
|
|
36
36
|
static void
|
37
37
|
_die( const char *format, ... ) {
|
@@ -594,6 +594,18 @@ get_checksum( uint16_t *pos, uint32_t size ) {
|
|
594
594
|
}
|
595
595
|
|
596
596
|
|
597
|
+
void
|
598
|
+
xfree_data( void *data, void *user_data ) {
|
599
|
+
UNUSED( user_data );
|
600
|
+
xfree( data );
|
601
|
+
}
|
602
|
+
|
603
|
+
|
604
|
+
bool
|
605
|
+
string_equal( void *data, void *user_data ) {
|
606
|
+
return strcmp( data, user_data ) == 0;
|
607
|
+
}
|
608
|
+
|
597
609
|
/*
|
598
610
|
* Local variables:
|
599
611
|
* c-basic-offset: 2
|
data/src/lib/utility.h
CHANGED
@@ -54,6 +54,9 @@ bool actions_to_string( const struct ofp_action_header *actions, uint16_t action
|
|
54
54
|
|
55
55
|
uint16_t get_checksum( uint16_t *pos, uint32_t size );
|
56
56
|
|
57
|
+
void xfree_data( void *data, void *user_data );
|
58
|
+
|
59
|
+
bool string_equal( void *data, void *user_data );
|
57
60
|
|
58
61
|
#endif // UTILITY_H
|
59
62
|
|
@@ -0,0 +1,120 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (C) 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
|
+
#include <assert.h>
|
19
|
+
#include "trema.h"
|
20
|
+
#include "event_forward_entry_manipulation.h"
|
21
|
+
|
22
|
+
|
23
|
+
void
|
24
|
+
management_event_forward_entry_add( list_element **service_list,
|
25
|
+
const event_forward_operation_request *request, size_t request_len ) {
|
26
|
+
if ( request->n_services == 0 ) return;
|
27
|
+
if ( request->n_services > 1 ) {
|
28
|
+
warn( "Only 1 service name expected for EVENT_FWD_ENTRY_ADD. Ignoring others." );
|
29
|
+
}
|
30
|
+
const size_t service_name_len = request_len - offsetof( event_forward_operation_request, service_list );
|
31
|
+
if ( service_name_len == 0 ) return;
|
32
|
+
|
33
|
+
char *service_name = xcalloc( service_name_len + 1, sizeof( char ) );
|
34
|
+
strncpy( service_name, request->service_list, service_name_len );
|
35
|
+
|
36
|
+
const char *match = find_list_custom( *service_list, string_equal, service_name );
|
37
|
+
if ( match == NULL ) {
|
38
|
+
info( "Adding '%s' to event filter.", service_name );
|
39
|
+
insert_in_front( service_list, service_name );
|
40
|
+
}
|
41
|
+
else {
|
42
|
+
// already there
|
43
|
+
xfree( service_name );
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
|
48
|
+
void
|
49
|
+
management_event_forward_entry_delete( list_element **service_list,
|
50
|
+
const event_forward_operation_request *request, size_t request_len ) {
|
51
|
+
if ( request->n_services == 0 ) return;
|
52
|
+
if ( request->n_services > 1 ) {
|
53
|
+
warn( "Only 1 service name expected for EVENT_FWD_ENTRY_DELETE. Ignoring others." );
|
54
|
+
}
|
55
|
+
const size_t service_name_len = request_len - offsetof( event_forward_operation_request, service_list );
|
56
|
+
if ( service_name_len == 0 ) return;
|
57
|
+
|
58
|
+
char *service_name = xcalloc( service_name_len + 1, sizeof( char ) );
|
59
|
+
strncpy( service_name, request->service_list, service_name_len );
|
60
|
+
|
61
|
+
const char *match = find_list_custom( *service_list, string_equal, service_name );
|
62
|
+
if ( match == NULL ) {
|
63
|
+
// didn't exist
|
64
|
+
xfree( service_name );
|
65
|
+
}
|
66
|
+
else {
|
67
|
+
info( "Deleting '%s' from event filter.", service_name );
|
68
|
+
bool success = delete_element( service_list, match );
|
69
|
+
assert( success );
|
70
|
+
}
|
71
|
+
}
|
72
|
+
|
73
|
+
|
74
|
+
void
|
75
|
+
management_event_forward_entries_set( list_element **service_list,
|
76
|
+
const event_forward_operation_request *request, size_t request_len ) {
|
77
|
+
const size_t service_name_list_len = request_len - offsetof( event_forward_operation_request, service_list );
|
78
|
+
|
79
|
+
const char **service_name_list = xcalloc( request->n_services, sizeof( char * ) );
|
80
|
+
|
81
|
+
// split null terminated string list.
|
82
|
+
unsigned int n_services = 0;
|
83
|
+
const char *name_begin = request->service_list;
|
84
|
+
for ( size_t i = 0 ; i < service_name_list_len ; ++i ) {
|
85
|
+
if ( request->service_list[ i ] == '\0' ) {
|
86
|
+
service_name_list[ n_services++ ] = name_begin;
|
87
|
+
if ( n_services == request->n_services ) {
|
88
|
+
if ( i + 1 != service_name_list_len ) {
|
89
|
+
warn( "Expecting %d name(s) for EVENT_FWD_ENTRY_SET, but more exist. Ignoring.", request->n_services );
|
90
|
+
}
|
91
|
+
break;
|
92
|
+
}
|
93
|
+
name_begin = &request->service_list[ i + 1 ];
|
94
|
+
}
|
95
|
+
}
|
96
|
+
if ( n_services != request->n_services ) {
|
97
|
+
warn( "Expected %d name(s) for EVENT_FWD_ENTRY_SET, but found %d.", request->n_services, n_services );
|
98
|
+
}
|
99
|
+
|
100
|
+
info( "Resetting event filter(s)." );
|
101
|
+
// clear current list
|
102
|
+
iterate_list( *service_list, xfree_data, NULL );
|
103
|
+
delete_list( *service_list );
|
104
|
+
create_list( service_list );
|
105
|
+
|
106
|
+
// set new list
|
107
|
+
for ( unsigned int i = 0 ; i < n_services ; ++i ) {
|
108
|
+
const size_t service_name_len = strlen( service_name_list[ i ] );
|
109
|
+
if ( service_name_len == 0 ) {
|
110
|
+
warn( "Ignoring 0 length service name in EVENT_FWD_ENTRY_SET" );
|
111
|
+
continue;
|
112
|
+
}
|
113
|
+
info( " Adding '%s' to event filter.", service_name_list[ i ] );
|
114
|
+
append_to_tail( service_list, xstrdup( service_name_list[ i ] ) );
|
115
|
+
}
|
116
|
+
|
117
|
+
xfree( service_name_list );
|
118
|
+
}
|
119
|
+
|
120
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (C) 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
|
+
#ifndef EVENT_FORWARD_ENTRY_MANIPULATION_H_
|
19
|
+
#define EVENT_FORWARD_ENTRY_MANIPULATION_H_
|
20
|
+
|
21
|
+
#include "event_forward_interface.h"
|
22
|
+
|
23
|
+
void management_event_forward_entry_add( list_element** service_list,
|
24
|
+
const event_forward_operation_request* request, size_t request_len );
|
25
|
+
void management_event_forward_entry_delete( list_element** service_list,
|
26
|
+
const event_forward_operation_request* request, size_t request_len );
|
27
|
+
void management_event_forward_entries_set( list_element** service_list,
|
28
|
+
const event_forward_operation_request* request, size_t request_len );
|
29
|
+
|
30
|
+
|
31
|
+
#endif /* EVENT_FORWARD_ENTRY_MANIPULATION_H_ */
|
@@ -30,6 +30,7 @@
|
|
30
30
|
#include "trema.h"
|
31
31
|
#include "secure_channel_listener.h"
|
32
32
|
#include "switch_manager.h"
|
33
|
+
#include "switch_option.h"
|
33
34
|
|
34
35
|
|
35
36
|
const int LISTEN_SOCK_MAX = 128;
|
@@ -165,7 +166,13 @@ secure_channel_listen_start( struct listener_info *listener_info ) {
|
|
165
166
|
|
166
167
|
static char **
|
167
168
|
make_switch_daemon_args( struct listener_info *listener_info, struct sockaddr_in *addr, int accept_fd ) {
|
168
|
-
int argc = SWITCH_MANAGER_DEFAULT_ARGC
|
169
|
+
const int argc = SWITCH_MANAGER_DEFAULT_ARGC
|
170
|
+
+ listener_info->switch_daemon_argc
|
171
|
+
+ ( int ) list_length_of( listener_info->vendor_service_name_list )
|
172
|
+
+ ( int ) list_length_of( listener_info->packetin_service_name_list )
|
173
|
+
+ ( int ) list_length_of( listener_info->portstatus_service_name_list )
|
174
|
+
+ ( int ) list_length_of( listener_info->state_service_name_list )
|
175
|
+
+ 1;
|
169
176
|
char **argv = xcalloc( ( size_t ) argc, sizeof( char * ) );
|
170
177
|
char *command_name = xasprintf( "%s%s:%u", SWITCH_MANAGER_COMMAND_PREFIX,
|
171
178
|
inet_ntoa( addr->sin_addr ),
|
@@ -191,6 +198,19 @@ make_switch_daemon_args( struct listener_info *listener_info, struct sockaddr_in
|
|
191
198
|
argv[ i ] = xstrdup( listener_info->switch_daemon_argv[ j ] );
|
192
199
|
}
|
193
200
|
|
201
|
+
for ( list_element *e = listener_info->vendor_service_name_list; e != NULL; e = e->next, ++i ) {
|
202
|
+
argv[ i ] = xasprintf( VENDOR_PREFIX "%s", e->data );
|
203
|
+
}
|
204
|
+
for ( list_element *e = listener_info->packetin_service_name_list; e != NULL; e = e->next, ++i ) {
|
205
|
+
argv[ i ] = xasprintf( PACKET_IN_PREFIX "%s", e->data );
|
206
|
+
}
|
207
|
+
for ( list_element *e = listener_info->portstatus_service_name_list; e != NULL; e = e->next, ++i ) {
|
208
|
+
argv[ i ] = xasprintf( PORTSTATUS_PREFIX "%s", e->data );
|
209
|
+
}
|
210
|
+
for ( list_element *e = listener_info->state_service_name_list; e != NULL; e = e->next, ++i ) {
|
211
|
+
argv[ i ] = xasprintf( STATE_PREFIX "%s", e->data );
|
212
|
+
}
|
213
|
+
|
194
214
|
return argv;
|
195
215
|
}
|
196
216
|
|
@@ -199,9 +219,9 @@ static void
|
|
199
219
|
free_switch_daemon_args( char **argv ) {
|
200
220
|
int i;
|
201
221
|
for ( i = 0; argv[ i ] != NULL; i++ ) {
|
202
|
-
|
222
|
+
xfree( argv[ i ] );
|
203
223
|
}
|
204
|
-
|
224
|
+
xfree( argv );
|
205
225
|
}
|
206
226
|
|
207
227
|
|
data/src/switch_manager/switch.c
CHANGED
@@ -26,9 +26,9 @@
|
|
26
26
|
#include <stdio.h>
|
27
27
|
#include <string.h>
|
28
28
|
#include <unistd.h>
|
29
|
+
#include <assert.h>
|
29
30
|
#include "trema.h"
|
30
31
|
#include "cookie_table.h"
|
31
|
-
#include "management_interface.h"
|
32
32
|
#include "message_queue.h"
|
33
33
|
#include "messenger.h"
|
34
34
|
#include "ofpmsg_send.h"
|
@@ -38,7 +38,8 @@
|
|
38
38
|
#include "service_interface.h"
|
39
39
|
#include "switch.h"
|
40
40
|
#include "xid_table.h"
|
41
|
-
|
41
|
+
#include "switch_option.h"
|
42
|
+
#include "event_forward_entry_manipulation.h"
|
42
43
|
|
43
44
|
#define SUB_TIMESPEC( _a, _b, _return ) \
|
44
45
|
do { \
|
@@ -52,23 +53,6 @@
|
|
52
53
|
while ( 0 )
|
53
54
|
|
54
55
|
|
55
|
-
enum long_options_val {
|
56
|
-
NO_FLOW_CLEANUP_LONG_OPTION_VALUE = 1,
|
57
|
-
NO_COOKIE_TRANSLATION_LONG_OPTION_VALUE = 2,
|
58
|
-
NO_PACKET_IN_LONG_OPTION_VALUE = 3,
|
59
|
-
};
|
60
|
-
|
61
|
-
static struct option long_options[] = {
|
62
|
-
{ "socket", 1, NULL, 's' },
|
63
|
-
{ "no-flow-cleanup", 0, NULL, NO_FLOW_CLEANUP_LONG_OPTION_VALUE },
|
64
|
-
{ "no-cookie-translation", 0, NULL, NO_COOKIE_TRANSLATION_LONG_OPTION_VALUE },
|
65
|
-
{ "no-packet_in", 0, NULL, NO_PACKET_IN_LONG_OPTION_VALUE },
|
66
|
-
{ NULL, 0, NULL, 0 },
|
67
|
-
};
|
68
|
-
|
69
|
-
static char short_options[] = "s:";
|
70
|
-
|
71
|
-
|
72
56
|
struct switch_info switch_info;
|
73
57
|
|
74
58
|
static const time_t COOKIE_TABLE_AGING_INTERVAL = 3600; // sec.
|
@@ -138,7 +122,7 @@ option_parser( int argc, char *argv[] ) {
|
|
138
122
|
switch_info.flow_cleanup = true;
|
139
123
|
switch_info.cookie_translation = true;
|
140
124
|
switch_info.deny_packet_in_on_startup = false;
|
141
|
-
while ( ( c = getopt_long( argc, argv,
|
125
|
+
while ( ( c = getopt_long( argc, argv, switch_short_options, switch_long_options, NULL ) ) != -1 ) {
|
142
126
|
switch ( c ) {
|
143
127
|
case 's':
|
144
128
|
switch_info.secure_channel_fd = strtofd( optarg );
|
@@ -498,6 +482,20 @@ switch_event_disconnected( struct switch_info *sw_info ) {
|
|
498
482
|
}
|
499
483
|
flush_messenger();
|
500
484
|
|
485
|
+
// free service name list
|
486
|
+
iterate_list( sw_info->vendor_service_name_list, xfree_data, NULL );
|
487
|
+
delete_list( sw_info->vendor_service_name_list );
|
488
|
+
sw_info->vendor_service_name_list = NULL;
|
489
|
+
iterate_list( sw_info->packetin_service_name_list, xfree_data, NULL );
|
490
|
+
delete_list( sw_info->packetin_service_name_list );
|
491
|
+
sw_info->packetin_service_name_list = NULL;
|
492
|
+
iterate_list( sw_info->portstatus_service_name_list, xfree_data, NULL );
|
493
|
+
delete_list( sw_info->portstatus_service_name_list );
|
494
|
+
sw_info->portstatus_service_name_list = NULL;
|
495
|
+
iterate_list( sw_info->state_service_name_list, xfree_data, NULL );
|
496
|
+
delete_list( sw_info->state_service_name_list );
|
497
|
+
sw_info->state_service_name_list = NULL;
|
498
|
+
|
501
499
|
stop_trema();
|
502
500
|
|
503
501
|
return 0;
|
@@ -539,10 +537,75 @@ switch_event_recv_error( struct switch_info *sw_info ) {
|
|
539
537
|
}
|
540
538
|
|
541
539
|
|
540
|
+
static void
|
541
|
+
management_event_forward_entry_operation( const messenger_context_handle *handle, uint32_t command, event_forward_operation_request *req, size_t data_len ) {
|
542
|
+
|
543
|
+
debug( "management efi command:%#x, type:%#x, n_services:%d", command, req->type, req->n_services );
|
544
|
+
|
545
|
+
list_element **subject = NULL;
|
546
|
+
switch ( req->type ) {
|
547
|
+
case EVENT_FORWARD_TYPE_VENDOR:
|
548
|
+
info( "Managing vendor event." );
|
549
|
+
subject = &switch_info.vendor_service_name_list;
|
550
|
+
break;
|
551
|
+
|
552
|
+
case EVENT_FORWARD_TYPE_PACKET_IN:
|
553
|
+
info( "Managing packet_in event." );
|
554
|
+
subject = &switch_info.packetin_service_name_list;
|
555
|
+
break;
|
556
|
+
|
557
|
+
case EVENT_FORWARD_TYPE_PORT_STATUS:
|
558
|
+
info( "Managing port_status event." );
|
559
|
+
subject = &switch_info.portstatus_service_name_list;
|
560
|
+
break;
|
561
|
+
|
562
|
+
case EVENT_FORWARD_TYPE_STATE_NOTIFY:
|
563
|
+
info( "Managing state_notify event." );
|
564
|
+
subject = &switch_info.state_service_name_list;
|
565
|
+
break;
|
566
|
+
|
567
|
+
default:
|
568
|
+
error( "Invalid EVENT_FWD_TYPE ( %#x )", req->type );
|
569
|
+
event_forward_operation_reply res;
|
570
|
+
memset( &res, 0, sizeof( event_forward_operation_reply ) );
|
571
|
+
res.type = req->type;
|
572
|
+
res.result = EFI_OPERATION_FAILED;
|
573
|
+
management_application_reply *reply = create_management_application_reply( MANAGEMENT_REQUEST_FAILED, command, &res, sizeof( event_forward_operation_reply ) );
|
574
|
+
send_management_application_reply( handle, reply );
|
575
|
+
xfree( reply );
|
576
|
+
return;
|
577
|
+
}
|
578
|
+
assert( subject != NULL );
|
579
|
+
|
580
|
+
switch ( command ) {
|
581
|
+
case EVENT_FORWARD_ENTRY_ADD:
|
582
|
+
management_event_forward_entry_add( subject, req, data_len );
|
583
|
+
break;
|
584
|
+
|
585
|
+
case EVENT_FORWARD_ENTRY_DELETE:
|
586
|
+
management_event_forward_entry_delete( subject, req, data_len );
|
587
|
+
break;
|
588
|
+
|
589
|
+
case EVENT_FORWARD_ENTRY_DUMP:
|
590
|
+
info( "Dumping current event filter." );
|
591
|
+
// do nothing
|
592
|
+
break;
|
593
|
+
|
594
|
+
case EVENT_FORWARD_ENTRY_SET:
|
595
|
+
management_event_forward_entries_set( subject, req, data_len );
|
596
|
+
break;
|
597
|
+
}
|
598
|
+
|
599
|
+
buffer *buf = create_event_forward_operation_reply( req->type, EFI_OPERATION_SUCCEEDED, *subject );
|
600
|
+
management_application_reply *reply = create_management_application_reply( MANAGEMENT_REQUEST_SUCCEEDED, command, buf->data, buf->length );
|
601
|
+
free_buffer( buf );
|
602
|
+
send_management_application_reply( handle, reply );
|
603
|
+
xfree( reply );
|
604
|
+
}
|
605
|
+
|
606
|
+
|
542
607
|
static void
|
543
608
|
management_recv( const messenger_context_handle *handle, uint32_t command, void *data, size_t data_len, void *user_data ) {
|
544
|
-
UNUSED( data );
|
545
|
-
UNUSED( data_len );
|
546
609
|
UNUSED( user_data );
|
547
610
|
|
548
611
|
switch ( command ) {
|
@@ -577,6 +640,18 @@ management_recv( const messenger_context_handle *handle, uint32_t command, void
|
|
577
640
|
}
|
578
641
|
break;
|
579
642
|
|
643
|
+
case EVENT_FORWARD_ENTRY_ADD:
|
644
|
+
case EVENT_FORWARD_ENTRY_DELETE:
|
645
|
+
case EVENT_FORWARD_ENTRY_DUMP:
|
646
|
+
case EVENT_FORWARD_ENTRY_SET:
|
647
|
+
{
|
648
|
+
event_forward_operation_request *req = data;
|
649
|
+
req->n_services = ntohl( req->n_services );
|
650
|
+
management_event_forward_entry_operation( handle, command, req, data_len );
|
651
|
+
return;
|
652
|
+
}
|
653
|
+
break;
|
654
|
+
|
580
655
|
default:
|
581
656
|
{
|
582
657
|
error( "Undefined management command ( %#x )", command );
|
@@ -623,14 +698,9 @@ main( int argc, char *argv[] ) {
|
|
623
698
|
create_list( &switch_info.portstatus_service_name_list );
|
624
699
|
create_list( &switch_info.state_service_name_list );
|
625
700
|
|
626
|
-
// FIXME
|
627
|
-
#define VENDER_PREFIX "vendor::"
|
628
|
-
#define PACKET_IN_PREFIX "packet_in::"
|
629
|
-
#define PORTSTATUS_PREFIX "port_status::"
|
630
|
-
#define STATE_PREFIX "state_notify::"
|
631
701
|
for ( i = optind; i < argc; i++ ) {
|
632
|
-
if ( strncmp( argv[ i ],
|
633
|
-
service_name = xstrdup( argv[ i ] + strlen(
|
702
|
+
if ( strncmp( argv[ i ], VENDOR_PREFIX, strlen( VENDOR_PREFIX ) ) == 0 ) {
|
703
|
+
service_name = xstrdup( argv[ i ] + strlen( VENDOR_PREFIX ) );
|
634
704
|
insert_in_front( &switch_info.vendor_service_name_list, service_name );
|
635
705
|
}
|
636
706
|
else if ( strncmp( argv[ i ], PACKET_IN_PREFIX, strlen( PACKET_IN_PREFIX ) ) == 0 ) {
|