static void handle_delete_filter_request( const messenger_context_handle *handle, delete_packetin_filter_request *request ) { assert( handle != NULL ); assert( request != NULL ); buffer *buf = alloc_buffer_with_length( sizeof( delete_packetin_filter_reply ) ); delete_packetin_filter_reply *reply = append_back_buffer( buf, sizeof( delete_packetin_filter_reply ) ); reply->status = PACKETIN_FILTER_OPERATION_SUCCEEDED; reply->n_deleted = 0; struct ofp_match match; ntoh_match( &match, &request->criteria.match ); uint16_t priority = ntohs( request->criteria.priority ); if ( request->flags & PACKETIN_FILTER_FLAG_MATCH_STRICT ) { int n_deleted = delete_packetin_match_entry( match, priority, request->criteria.service_name ); reply->n_deleted += ( uint32_t ) n_deleted; } else { map_match_table( match, delete_filter_walker, buf ); } reply->n_deleted = htonl( reply->n_deleted ); bool ret = send_reply_message( handle, MESSENGER_DELETE_PACKETIN_FILTER_REPLY, buf->data, buf->length ); free_buffer( buf ); if ( ret == false ) { error( "Failed to send a dump filter reply." ); } }
static void handle_dump_filter_request( const messenger_context_handle *handle, dump_packetin_filter_request *request ) { assert( handle != NULL ); assert( request != NULL ); buffer *buf = alloc_buffer_with_length( 2048 ); dump_packetin_filter_reply *reply = append_back_buffer( buf, offsetof( dump_packetin_filter_reply, entries ) ); reply->status = PACKETIN_FILTER_OPERATION_SUCCEEDED; reply->n_entries = 0; struct ofp_match match; ntoh_match( &match, &request->criteria.match ); uint16_t priority = ntohs( request->criteria.priority ); if ( request->flags & PACKETIN_FILTER_FLAG_MATCH_STRICT ) { list_element *services = lookup_match_strict_entry( match, priority ); while ( services != NULL ) { if ( strcmp( services->data, request->criteria.service_name ) == 0 ) { packetin_filter_entry *entry = append_back_buffer( buf, sizeof( packetin_filter_entry ) ); reply->n_entries++; entry->match = request->criteria.match; entry->priority = request->criteria.priority; strncpy( entry->service_name, services->data, sizeof( entry->service_name ) ); entry->service_name[ sizeof( entry->service_name ) - 1 ] = '\0'; } services = services->next; } } else { map_match_table( match, dump_filter_walker, buf ); } reply->n_entries = htonl( reply->n_entries ); bool ret = send_reply_message( handle, MESSENGER_DUMP_PACKETIN_FILTER_REPLY, buf->data, buf->length ); free_buffer( buf ); if ( ret == false ) { error( "Failed to send a dump packetin filter reply." ); } }
static void handle_add_filter_request( const messenger_context_handle *handle, add_packetin_filter_request *request ) { assert( handle != NULL ); assert( request != NULL ); request->entry.service_name[ MESSENGER_SERVICE_NAME_LENGTH - 1 ] = '\0'; if ( strlen( request->entry.service_name ) == 0 ) { error( "Service name must be specified." ); return; } struct ofp_match match; ntoh_match( &match, &request->entry.match ); bool ret = add_packetin_match_entry( match, ntohs( request->entry.priority ), request->entry.service_name ); add_packetin_filter_reply reply; memset( &reply, 0, sizeof( add_packetin_filter_reply ) ); reply.status = ( uint8_t ) ( ret ? PACKETIN_FILTER_OPERATION_SUCCEEDED : PACKETIN_FILTER_OPERATION_FAILED ); ret = send_reply_message( handle, MESSENGER_ADD_PACKETIN_FILTER_REPLY, &reply, sizeof( add_packetin_filter_reply ) ); if ( ret == false ) { error( "Failed to send an add filter reply." ); } }
static void ntoh_packetin_filter_entry( packetin_filter_entry *dst, packetin_filter_entry *src ) { ntoh_match( &dst->match, &src->match ); dst->priority = ntohs( src->priority ); memcpy( dst->service_name, src->service_name, sizeof( dst->service_name ) ); }