int mirroring_receive(phv_data_t *phv, int *metadata_recirc, void *pkt_data,
                      int len, uint64_t packet_id,
                      pkt_instance_type_t instance_type) {
  int mirror_id = fields_get_clone_spec(phv);
  coalescing_session_t *coalescing_session = get_coalescing_session(mirror_id);
  if(NULL != coalescing_session) {
    RMT_LOG(P4_LOG_LEVEL_VERBOSE,
      "Queuing digest for mirror %d %d\n", mirror_id, *metadata_recirc);
    pkt_digest_t *pkt_digest = malloc(sizeof(pkt_digest_t));
    pkt_digest->mirror_id = mirror_id;
    pkt_digest->length = 0;
    deparser_extract_digest(phv, metadata_recirc, pkt_digest->buffer, &(pkt_digest->length));

    cb_write(rmt_mirroring_cb, pkt_digest);
  }
  else if(NULL != get_mirroring_mapping(mirror_id)) {
    uint8_t *metadata;
    deparser_produce_metadata(phv, &metadata);
//::  if enable_intrinsic:
//::    bytes = 0
//::    for header_instance in ordered_header_instances_non_virtual:
//::      h_info = header_info[header_instance]
//::      is_metadata = h_info["is_metadata"]
//::      if is_metadata: bytes += h_info["byte_width_phv"]
//::    #endfor
     uint8_t extracted_metadata[${bytes}];
     metadata_extract(extracted_metadata, metadata, NULL); /* NULL ? */
    // do not set deflection_flag and dod bits for mirrored packet
    metadata_set_deflection_flag(extracted_metadata, 0);
    metadata_set_deflect_on_drop(extracted_metadata, 0);
    metadata_dump(metadata, extracted_metadata);
//::  #endif

    return queuing_receive(metadata, metadata_recirc, pkt_data, len, packet_id,
                           instance_type);
  }
  else {
    RMT_LOG(P4_LOG_LEVEL_WARN,
            "Received packet with invalid mirror id %d\n", mirror_id);
  }

  free(pkt_data);
  free(metadata_recirc);

  return 0;
}
Exemple #2
0
static void *pkt_processing_loop(void *arg) {
  while(1) {
    queuing_pkt_t *q_pkt = (queuing_pkt_t *) cb_read(rmt_queuing_cb);
    buffered_pkt_t *b_pkt = &q_pkt->pkt;
    RMT_LOG(P4_LOG_LEVEL_TRACE, "queuing system: packet dequeued\n");
    memset(metadata, 0, ${bytes});
    metadata_extract(metadata, q_pkt->metadata, q_pkt->metadata_recirc);

    /* after this point, no one should use q_pkt->metadata */

    int mirror_id = metadata_get_clone_spec(metadata);
    metadata_set_clone_spec(metadata, 0);
    int egress_port;
//:: if enable_pre:
    if (pre_replication(q_pkt, metadata)) {
      continue;
    }
//:: #endif
    if(mirror_id == 0) {
      egress_port = metadata_get_egress_spec(metadata);
      /* TODO: formalize somewhere that 511 is the drop port for this target */
//:: if "ingress_drop_ctl" in extra_metadata_name_map:
      // program uses the separate ingress_drop_ctl register
      // a non-zero value means drop
      if(egress_port = 511 || metadata_get_ingress_drop_ctl(metadata)) {
//:: else:
      if(egress_port == 511) {
//:: #endif
	RMT_LOG(P4_LOG_LEVEL_VERBOSE, "dropping packet at ingress\n");
	free(b_pkt->pkt_data);
	free(q_pkt->metadata);
	free(q_pkt->metadata_recirc);
	free(q_pkt);
	continue;
      }
    }
    else {
      RMT_LOG(P4_LOG_LEVEL_VERBOSE, "mirror id is %d\n", mirror_id);
      egress_port = ${pd_prefix}mirroring_mapping_get_egress_port(mirror_id);
      if (egress_port < 0) {
	RMT_LOG(P4_LOG_LEVEL_WARN,
		"no mapping for mirror id %d, dropping packet\n", mirror_id);
	free(b_pkt->pkt_data);
	free(q_pkt->metadata);
	free(q_pkt->metadata_recirc);
	free(q_pkt);
	continue;
      }
      RMT_LOG(P4_LOG_LEVEL_TRACE,
             "queuing system: cloned packet, mirror_id -> egress_port : %d -> %d\n",
             mirror_id, egress_port);
    }
    metadata_set_egress_port(metadata, egress_port);
    RMT_LOG(P4_LOG_LEVEL_TRACE, "egress port set to %d\n", egress_port);

    pkt_instance_type_t instance_type = b_pkt->instance_type;
    metadata_set_instance_type(metadata, instance_type);
    RMT_LOG(P4_LOG_LEVEL_TRACE, "instance type set to %d\n", instance_type);

//::  if enable_intrinsic:
    /* Set enqueue metadata */
    metadata_set_enq_qdepth(metadata, egress_pipeline_count(egress_port));
    metadata_set_enq_timestamp(metadata, get_timestamp());
//::  #endif 
    
    metadata_dump(q_pkt->metadata, metadata);
    egress_pipeline_receive(egress_port,
			    q_pkt->metadata, q_pkt->metadata_recirc,
			    b_pkt->pkt_data, b_pkt->pkt_len, b_pkt->pkt_id,
			    b_pkt->instance_type);
    free(q_pkt);
  }

  return NULL;
}
Exemple #3
0
int egress_pipeline_receive(int egress,
			    uint8_t *metadata,
			    int *metadata_recirc,
			    void *pkt, int len, uint64_t packet_id,
			    pkt_instance_type_t instance_type) {
  pipeline_t *pipeline = egress_pipeline_instances[egress %
						   NB_THREADS_PER_PIPELINE];
  
  egress_pkt_t *e_pkt = malloc(sizeof(egress_pkt_t));
  buffered_pkt_t *b_pkt = &e_pkt->pkt;
  e_pkt->egress = egress;
  e_pkt->metadata = metadata;
  e_pkt->metadata_recirc = metadata_recirc;
  b_pkt->instance_type = instance_type;
  b_pkt->pkt_data = pkt;
  b_pkt->pkt_len = len;
  b_pkt->pkt_id = packet_id;

//::  if enable_intrinsic:
//::    bytes = 0
//::    for header_instance in ordered_header_instances_non_virtual:
//::      h_info = header_info[header_instance]
//::      is_metadata = h_info["is_metadata"]
//::      if is_metadata: bytes += h_info["byte_width_phv"]
//::    #endfor
  uint8_t extracted_metadata[${bytes}];
  metadata_extract(extracted_metadata, metadata, NULL); /* NULL ? */
  uint32_t deflect_on_drop = metadata_get_deflect_on_drop(extracted_metadata);
  if (!deflect_on_drop) {
    int ret = cb_write(pipeline->cb_in, e_pkt);
    if (ret == 0) {
      free(e_pkt);
      RMT_LOG(P4_LOG_LEVEL_TRACE, "egress_pipeline: dropped a packet from tail\n");
    }
  } else {
    // For negative mirroring based on Qfull,
    // Set the deflection_flag in metadata to indicate that this packet 
    // is moving thru' the queuing system only to get delivered to 
    // negative mirror session.
    // Egress pipeline should act on the deflection_flag and perform 
    // explicit e2e mirroing as appropriate
    RMT_LOG(P4_LOG_LEVEL_TRACE, "egress_pipeline: deflect tail-dropped packet %p\n", metadata);
    metadata_set_deflection_flag(extracted_metadata, 1);
    metadata_set_deflect_on_drop(extracted_metadata, 0);
    metadata_set_egress_spec(extracted_metadata, 0);
    metadata_set_egress_port(extracted_metadata, 0);
    metadata_dump(metadata, extracted_metadata);
    int ret = cb_write(pipeline->cb_in, e_pkt);
    if (ret ==0) {
      free(e_pkt);
      RMT_LOG(P4_LOG_LEVEL_TRACE, "egress_pipeline: could not enqueue a deflected packet\n");
    }
  }
//::  #endif
//::  if not enable_intrinsic:
  int ret = cb_write(pipeline->cb_in, e_pkt);
  if (ret == 0) {
    free(e_pkt);
    RMT_LOG(P4_LOG_LEVEL_TRACE, "egress_pipeline: dropped a packet from tail\n");
  }
//::  #endif

  return 0;
}