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