Example #1
0
/*
 * ecm_tracker_tcp_alloc()
 */
struct ecm_tracker_tcp_instance *ecm_tracker_tcp_alloc(void)
{
	struct ecm_tracker_tcp_internal_instance *ttii;

	ttii = (struct ecm_tracker_tcp_internal_instance *)kzalloc(sizeof(struct ecm_tracker_tcp_internal_instance), GFP_ATOMIC | __GFP_NOWARN);
	if (!ttii) {
		DEBUG_WARN("Failed to allocate tcp tracker instance\n");
		return NULL;
	}

	ttii->tcp_base.base.ref = ecm_tracker_tcp_ref_callback;
	ttii->tcp_base.base.deref = ecm_tracker_tcp_deref_callback;
	ttii->tcp_base.base.state_update = ecm_tracker_tcp_state_update_callback;
	ttii->tcp_base.base.state_get = ecm_tracker_tcp_state_get_callback;

	spin_lock_init(&ttii->lock);

	ttii->refs = 1;
	DEBUG_SET_MAGIC(ttii, ECM_TRACKER_TCP_INSTANCE_MAGIC);

	spin_lock_bh(&ecm_tracker_tcp_lock);
	ecm_tracker_tcp_count++;
	DEBUG_ASSERT(ecm_tracker_tcp_count > 0, "%p: tcp tracker count wrap\n", ttii);
	spin_unlock_bh(&ecm_tracker_tcp_lock);

	DEBUG_TRACE("TCP tracker created %p\n", ttii);
	return (struct ecm_tracker_tcp_instance *)ttii;
}
/*
 * ecm_state_char_device_open()
 *	Opens the special char device file which we use to dump our state.
 */
static int ecm_state_char_device_open(struct inode *inode, struct file *file)
{
	struct ecm_state_file_instance *sfi;

	DEBUG_INFO("State open\n");

	/*
	 * Allocate state information for the reading
	 */
	DEBUG_ASSERT(file->private_data == NULL, "unexpected double open: %p?\n", file->private_data);

	sfi = (struct ecm_state_file_instance *)kzalloc(sizeof(struct ecm_state_file_instance), GFP_ATOMIC | __GFP_NOWARN);
	if (!sfi) {
		return -ENOMEM;
	}
	DEBUG_SET_MAGIC(sfi, ECM_STATE_FILE_INSTANCE_MAGIC);
	file->private_data = sfi;

	/*
	 * Snapshot output mask for this file
	 */
	spin_lock_bh(&ecm_state_lock);
	sfi->output_mask = ecm_state_file_output_mask;
	spin_unlock_bh(&ecm_state_lock);

	/*
	 * Get the first indicies for hash and protocol stats should they be needed.
	 * NOTE: There are no references held here so it does not matter to get them all even if they are not wanted.
	 */
	sfi->connection_hash_index = ecm_db_connection_hash_index_get_first();
	sfi->mapping_hash_index = ecm_db_mapping_hash_index_get_first();
	sfi->host_hash_index = ecm_db_host_hash_index_get_first();
	sfi->node_hash_index = ecm_db_node_hash_index_get_first();
	sfi->iface_hash_index = ecm_db_iface_hash_index_get_first();
	sfi->protocol = ecm_db_protocol_get_first();

	/*
	 * Take references to each object list that we are going to generate state for.
	 */
	if (sfi->output_mask & ECM_STATE_FILE_OUTPUT_CONNECTIONS) {
		sfi->ci = ecm_db_connections_get_and_ref_first();
	}
	if (sfi->output_mask & ECM_STATE_FILE_OUTPUT_MAPPINGS) {
		sfi->mi = ecm_db_mappings_get_and_ref_first();
	}
	if (sfi->output_mask & ECM_STATE_FILE_OUTPUT_HOSTS) {
		sfi->hi = ecm_db_hosts_get_and_ref_first();
	}
	if (sfi->output_mask & ECM_STATE_FILE_OUTPUT_NODES) {
		sfi->ni = ecm_db_nodes_get_and_ref_first();
	}
	if (sfi->output_mask & ECM_STATE_FILE_OUTPUT_INTERFACES) {
		sfi->ii = ecm_db_interfaces_get_and_ref_first();
	}
#ifdef ECM_DB_CTA_TRACK_ENABLE
	if (sfi->output_mask & ECM_STATE_FILE_OUTPUT_CLASSIFIER_TYPE_ASSIGNMENTS) {
		ecm_classifier_type_t ca_type;

		/*
		 * Iterate all classifier type assignments.
		 * Hold the head of each list to start us off on our iterating process.
		 */
		for (ca_type = 0; ca_type < ECM_CLASSIFIER_TYPES; ++ca_type) {
			sfi->classifier_type_assignments[ca_type] = ecm_db_connection_by_classifier_type_assignment_get_and_ref_first(ca_type);
		}
	}
#endif

	DEBUG_INFO("State opened %p\n", sfi);

	return 0;
}