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
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;
}