void add_flow(u_int8_t dst[6],u_int8_t src[6],u_int16_t frame_type,u_int8_t inport,u_int8_t outport,u_int8_t idx)
{
    struct sw_flow *flow = malloc(sizeof(struct sw_flow));
    memset((char *)flow,0,16);
    flow->valid = 1;
    flow->input_port = inport;
    flow->action = outport;
    flow->frame_type = htons(frame_type);
    memcpy(flow->src_mac, src , 6);
    memcpy(flow->dst_mac, dst , 6);
    if ( add_flow_entry(flow, idx) == 0) {
        printf("add succ\n");
    }
    else
        printf("add failed!\n");
    free(flow);
}
Beispiel #2
0
OFDPE
update_or_add_flow_entry( const uint8_t table_id, const match *key,
                          const uint64_t cookie, const uint64_t cookie_mask,
                          const uint16_t priority, const uint16_t idle_timeout, const uint16_t hard_timeout,
                          const uint16_t flags, const bool strict, instruction_set *instructions ) {
  if ( !valid_table_id( table_id ) ) {
    return ERROR_OFDPE_FLOW_MOD_FAILED_BAD_TABLE_ID;
  }

  if ( key == NULL ) {
    error( "Invalid match ( %p ).", key );
    return ERROR_INVALID_PARAMETER;
  }
  if ( instructions == NULL ) {
    error( "Invalid instruction set ( %p ).", instructions );
    return ERROR_INVALID_PARAMETER;
  }

  if ( !lock_pipeline() ) {
    return ERROR_LOCK;
  }

  flow_table *table = get_flow_table( table_id );
  assert( table != NULL );

  OFDPE ret = validate_instruction_set( instructions, table->features.metadata_write );
  if ( ret != OFDPE_SUCCESS ) {
    error( "Invalid instruction set ( ret = %#x, instructions = %p ).", ret, instructions );
    unlock_pipeline();
    return ret;
  }

  list_element *list = lookup_flow_entries_with_table_id( table_id, key, priority, strict, false );
  if ( list != NULL ) {
    update_flow_entries_in_list( list, cookie, cookie_mask, flags, instructions );
    delete_list( list );
  }
  else {
    match *duplicated_match = duplicate_match( key );
    instruction_set *duplicated_instructions = duplicate_instructions( instructions );
    flow_entry *entry = alloc_flow_entry( duplicated_match, duplicated_instructions,
                                          priority, idle_timeout, hard_timeout, flags, cookie );
    if ( entry != NULL ) {
      ret = add_flow_entry( table_id, entry, flags );
      if ( ret != OFDPE_SUCCESS ) {
        error( "Failed to add flow entry ( table_id = %#x, entry = %p, flags = %#x ).", table_id, entry, flags );
      }
    }
    else { 
      delete_match( duplicated_match );
      delete_instructions( duplicated_instructions );
      ret = OFDPE_FAILED;
    }
  }

  if ( !unlock_pipeline() ) {
    return ERROR_UNLOCK;
  }

  return ret;
}
Beispiel #3
0
static void
handle_flow_mod_add( const uint32_t transaction_id, const uint64_t cookie, 
                     const uint64_t cookie_mask, const uint8_t table_id,
                     const uint16_t idle_timeout, const uint16_t hard_timeout,
                     const uint16_t priority, const uint32_t buffer_id,
                     const uint16_t flags, const oxm_matches *oxm,
                     const openflow_instructions *instructions,
                     struct protocol *protocol ) {
  UNUSED( cookie_mask );
  /*
   * currently if flags set OFPFF_SEND_FLOW_REM and OFPFF_RESET_COUNTS are the only allowed value.
   */
  if ( ( flags & ~( OFPFF_SEND_FLOW_REM | OFPFF_RESET_COUNTS ) ) != 0 ) {
    send_error_message( transaction_id, OFPET_FLOW_MOD_FAILED, OFPFMFC_BAD_FLAGS );
    return;
  }
  /*
   * The use of OFPTT_ALL is only valid for delete requests.
   */
  if ( table_id == OFPTT_ALL ) {
    send_error_message( transaction_id, OFPET_FLOW_MOD_FAILED, OFPFMFC_BAD_TABLE_ID );
    return;
  }

  /*
   * If no buffered packet is associated with a flow mod it must be set
   * to OFP_NO_BUFFER otherwise it must be equal to the buffer_id sent to
   * controller by a packet-in message.
   */

  match *match = create_match();
  if ( oxm != NULL && oxm->n_matches > 0 ) {
    
#ifdef DEBUG    
    char oxm_str[ 2048 ];
    match_to_string( oxm, oxm_str, sizeof( oxm_str ) );
    printf( "%s\n", oxm_str );
#endif
    
    for ( list_element *e = oxm->list; e != NULL; e = e->next ) {
      oxm_match_header *hdr = e->data;
      assign_match( match, hdr );
    }
  }

  instruction_set *instruction_set = create_instruction_set();
  if ( instructions != NULL ) {
    OFDPE ret = assign_instructions( instruction_set, instructions->list );
    if ( ret != OFDPE_SUCCESS ) {
      send_error_message( transaction_id, OFPET_FLOW_MOD_FAILED, OFPBIC_UNSUP_INST );
      delete_instruction_set( instruction_set );
      delete_match( match );
      return;
    }
  }

  /*
   * When a flow entry is inserted in a table, its flags field is set with the
   * values from the message.
   * When a flow entry is inserted in a table, its idle_timeout and
   * hard_timeout fields are set with the values from the message.
   * When a flow entry is inserted in a table through an OFPFC_ADD message,
   * its cookie field is set to the provided value
   */
  flow_entry *new_entry = alloc_flow_entry( match, instruction_set, priority,
                                            idle_timeout, hard_timeout, flags, cookie );
  if ( new_entry == NULL ) {
    /*
     * TODO we should send a more appropriate error once we worked out the
     * datapath errors.
     */
    delete_instruction_set( instruction_set );
    delete_match( match );
    send_error_message( transaction_id, OFPET_FLOW_MOD_FAILED, OFPFMFC_UNKNOWN );
    return;
  }

  OFDPE ret = add_flow_entry( table_id, new_entry, flags );
  if ( ret != OFDPE_SUCCESS ) {
    error( "Failed to add a flow entry ( ret = %d ).", ret );
    delete_instruction_set( instruction_set );
    delete_match( match );

    uint16_t type = OFPET_FLOW_MOD_FAILED;
    uint16_t code = OFPFMFC_UNKNOWN;
    get_ofp_error( ret, &type, &code );
    send_error_message( transaction_id, type, code );
    return;
  }

  if ( buffer_id != OFP_NO_BUFFER ) {
    action_list *actions = create_action_list();
    action *action = create_action_output( OFPP_TABLE, UINT16_MAX );
    append_action( actions, action );
    ret = execute_packet_out( buffer_id, 0, actions, NULL );
    delete_action_list( actions );
    if ( ret != OFDPE_SUCCESS ) {
      uint16_t type = OFPET_FLOW_MOD_FAILED;
      uint16_t code = OFPFMFC_UNKNOWN;
      get_ofp_error( ret, &type, &code );
      send_error_message( transaction_id, type, code );
      return;
    }
    wakeup_datapath( protocol );
  }
}