コード例 #1
0
static openflow_actions *
create_openflow_actions_to_update_vid( uint16_t in_vid, uint16_t out_vid ) {
  if ( in_vid == out_vid ) {
    return NULL;
  }

  openflow_actions *vlan_actions = create_actions();
  if ( out_vid == VLAN_NONE ) {
    append_action_strip_vlan( vlan_actions );
  }
  else {
    append_action_set_vlan_vid( vlan_actions, out_vid );
  }
  return vlan_actions;
}
コード例 #2
0
static int
build_packet_out_actions( port_info *port, void *user_data ) {
  if ( !port->external_link || port->switch_to_switch_reverse_link ) {
    // don't send to non-external port
    return 0;
  }

  port_params *params = user_data;

  if ( port->dpid == params->switch_params->in_datapath_id &&
       port->port_no == params->switch_params->in_port ) {
    // don't send to input port
    return 0;
  }

  int n_actions_original = params->actions->n_actions;
  uint16_t slice = params->switch_params->slice;
  uint16_t out_vid = params->switch_params->in_vid;
  bool found = get_port_vid( slice, port->dpid, port->port_no, &out_vid );
  if ( found ) {
    if ( out_vid == VLAN_NONE ) {
      append_action_strip_vlan( params->actions );
    }
    else {
      append_action_set_vlan_vid( params->actions, out_vid );
    }
  }
  else {
    if ( !loose_mac_based_slicing_enabled() ) {
      return 0;
    }
    if ( !mac_slice_maps_exist( slice ) ) {
      return 0;
    }
  }

  const uint16_t max_len = UINT16_MAX;
  append_action_output( params->actions, port->port_no, max_len );

  return params->actions->n_actions - n_actions_original;
}
コード例 #3
0
static void
output_packet( const buffer *packet, uint64_t dpid, uint16_t port_no, uint16_t out_vid ) {

  openflow_actions *actions = create_actions();
  uint16_t in_vid = VLAN_NONE;
  if ( packet_type_eth_vtag( packet ) ) {
    packet_info packet_info = get_packet_info( packet );
    in_vid = packet_info.vlan_vid;
  }
  if ( out_vid != in_vid ) {
    if ( in_vid != VLAN_NONE && out_vid == VLAN_NONE ) {
      append_action_strip_vlan( actions );
    }
    else {
      append_action_set_vlan_vid( actions, out_vid );
    }
  }
  const uint16_t max_len = UINT16_MAX;
  append_action_output( actions, port_no, max_len );

  send_packet_out( dpid, actions, packet );
  delete_actions( actions );
}
コード例 #4
0
ファイル: controller.c プロジェクト: aigamo/trema
static void
append_action( openflow_actions *actions, VALUE action ) {
  if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::Enqueue" ) ) == Qtrue ) {
    uint32_t queue_id = ( uint32_t ) NUM2UINT( rb_funcall( action, rb_intern( "queue_id" ), 0 ) );
    uint16_t port_number = ( uint16_t ) NUM2UINT( rb_funcall( action, rb_intern( "port_number" ), 0 ) );
    append_action_enqueue( actions, port_number, queue_id );
  }
  else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SendOutPort" ) ) == Qtrue ) {
    uint16_t port_number = ( uint16_t ) NUM2UINT( rb_funcall( action, rb_intern( "port_number" ), 0 ) );
    uint16_t max_len = ( uint16_t ) NUM2UINT( rb_funcall( action, rb_intern( "max_len" ), 0 ) );
    append_action_output( actions, port_number, max_len );
  }
  else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetEthDstAddr" ) ) == Qtrue ) {
    uint8_t dl_dst[ OFP_ETH_ALEN ];
    uint8_t *ptr = ( uint8_t * ) dl_addr_to_a( rb_funcall( action, rb_intern( "mac_address" ), 0 ), dl_dst );
    append_action_set_dl_dst( actions, ptr );
  }
  else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetEthSrcAddr" ) ) == Qtrue ) {
    uint8_t dl_src[ OFP_ETH_ALEN ];
    uint8_t *ptr = ( uint8_t * ) dl_addr_to_a( rb_funcall( action, rb_intern( "mac_address" ), 0 ), dl_src );
    append_action_set_dl_src( actions, ptr );
  }
  else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetIpDstAddr" ) ) == Qtrue ) {
    append_action_set_nw_dst( actions, nw_addr_to_i( rb_funcall( action, rb_intern( "ip_address" ), 0 ) ) );
  }
  else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetIpSrcAddr" ) ) == Qtrue ) {
    append_action_set_nw_src( actions, nw_addr_to_i( rb_funcall( action, rb_intern( "ip_address" ), 0 ) ) );
  }
  else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetIpTos" ) ) == Qtrue ) {
    append_action_set_nw_tos( actions, ( uint8_t ) NUM2UINT( rb_funcall( action, rb_intern( "type_of_service" ), 0 ) ) );
  }
  else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetTransportDstPort" ) ) == Qtrue ) {
    append_action_set_tp_dst( actions, ( uint16_t ) NUM2UINT( rb_funcall( action, rb_intern( "port_number" ), 0 ) ) );
  }
  else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetTransportSrcPort" ) ) == Qtrue ) {
    append_action_set_tp_src( actions, ( uint16_t ) NUM2UINT( rb_funcall( action, rb_intern( "port_number" ), 0 ) ) );
  }
  else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetVlanPriority" ) ) == Qtrue ) {
    append_action_set_vlan_pcp( actions, ( uint8_t ) NUM2UINT( rb_funcall( action, rb_intern( "vlan_priority" ), 0 ) ) );
  }
  else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetVlanVid" ) ) == Qtrue ) {
    append_action_set_vlan_vid( actions, ( uint16_t ) NUM2UINT( rb_funcall( action, rb_intern( "vlan_id" ), 0 ) ) );
  }
  else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::StripVlanHeader" ) ) == Qtrue ) {
    append_action_strip_vlan( actions );
  }
  else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::VendorAction" ) ) == Qtrue ) {
    VALUE vendor_id = rb_funcall( action, rb_intern( "vendor_id" ), 0 );
    VALUE rbody = rb_funcall( action, rb_intern( "body" ), 0 );
    if ( rbody != Qnil ) {
      Check_Type( rbody, T_ARRAY );
      uint16_t length = ( uint16_t ) RARRAY_LEN( rbody );
      buffer *body = alloc_buffer_with_length( length );
      void *p = append_back_buffer( body, length );
      for ( int i = 0; i < length; i++ ) {
        ( ( uint8_t * ) p )[ i ] = ( uint8_t ) FIX2INT( RARRAY_PTR( rbody )[ i ] );
      }
      append_action_vendor( actions, ( uint32_t ) NUM2UINT( vendor_id ), body );
      free_buffer( body );
    }
    else {
      append_action_vendor( actions, ( uint32_t ) NUM2UINT( vendor_id ), NULL );
    }
  }
  else {
    rb_raise( rb_eTypeError, "actions argument must be an Array of Action objects" );
  }
}