static struct dp_packet_batch * prepare_packets(size_t n, bool change, unsigned tid, ovs_be16 *dl_type) { struct dp_packet_batch *pkt_batch = xzalloc(sizeof *pkt_batch); struct flow flow; size_t i; ovs_assert(n <= ARRAY_SIZE(pkt_batch->packets)); dp_packet_batch_init(pkt_batch); for (i = 0; i < n; i++) { struct udp_header *udp; struct dp_packet *pkt = dp_packet_new(sizeof payload/2); dp_packet_put_hex(pkt, payload, NULL); flow_extract(pkt, &flow); udp = dp_packet_l4(pkt); udp->udp_src = htons(ntohs(udp->udp_src) + tid); if (change) { udp->udp_dst = htons(ntohs(udp->udp_dst) + i); } dp_packet_batch_add(pkt_batch, pkt); *dl_type = flow.dl_type; } return pkt_batch; }
int main(int argc OVS_UNUSED, char *argv[]) { struct ofp_match expected_match; FILE *flows, *pcap; int retval; int n = 0, errors = 0; set_program_name(argv[0]); flows = stdin; pcap = fdopen(3, "rb"); if (!pcap) { ovs_fatal(errno, "failed to open fd 3 for reading"); } retval = pcap_read_header(pcap); if (retval) { ovs_fatal(retval > 0 ? retval : 0, "reading pcap header failed"); } while (fread(&expected_match, sizeof expected_match, 1, flows)) { struct ofpbuf *packet; struct ofp_match extracted_match; struct cls_rule rule; struct flow flow; n++; retval = pcap_read(pcap, &packet); if (retval == EOF) { ovs_fatal(0, "unexpected end of file reading pcap file"); } else if (retval) { ovs_fatal(retval, "error reading pcap file"); } flow_extract(packet, 0, 1, &flow); cls_rule_init_exact(&flow, 0, &rule); ofputil_cls_rule_to_match(&rule, &extracted_match); if (memcmp(&expected_match, &extracted_match, sizeof expected_match)) { char *exp_s = ofp_match_to_string(&expected_match, 2); char *got_s = ofp_match_to_string(&extracted_match, 2); errors++; printf("mismatch on packet #%d (1-based).\n", n); printf("Packet:\n"); ofp_print_packet(stdout, packet->data, packet->size, packet->size); ovs_hex_dump(stdout, packet->data, packet->size, 0, true); printf("Expected flow:\n%s\n", exp_s); printf("Actually extracted flow:\n%s\n", got_s); printf("\n"); free(exp_s); free(got_s); } ofpbuf_delete(packet); } printf("checked %d packets, %d errors\n", n, errors); return errors != 0; }
static void pcap_batch_execute_conntrack(struct conntrack *ct_, struct dp_packet_batch *pkt_batch) { struct dp_packet_batch new_batch; ovs_be16 dl_type = htons(0); long long now = time_msec(); dp_packet_batch_init(&new_batch); /* pkt_batch contains packets with different 'dl_type'. We have to * call conntrack_execute() on packets with the same 'dl_type'. */ struct dp_packet *packet; DP_PACKET_BATCH_FOR_EACH (i, packet, pkt_batch) { struct flow flow; /* This also initializes the l3 and l4 pointers. */ flow_extract(packet, &flow); if (dp_packet_batch_is_empty(&new_batch)) { dl_type = flow.dl_type; } if (flow.dl_type != dl_type) { conntrack_execute(ct_, &new_batch, dl_type, false, true, 0, NULL, NULL, 0, 0, NULL, NULL, now); dp_packet_batch_init(&new_batch); } dp_packet_batch_add(&new_batch, packet); } if (!dp_packet_batch_is_empty(&new_batch)) { conntrack_execute(ct_, &new_batch, dl_type, false, true, 0, NULL, NULL, 0, 0, NULL, NULL, now); } }