From c6252097fb812d522d31aa48ebd259864e9f9a03 Mon Sep 17 00:00:00 2001 From: jsonch Date: Tue, 2 Jul 2024 11:52:46 -0400 Subject: [PATCH] generator finally working as expected after fixing surprising bug only found in physical asic (not ref. model) --- examples/utils/generator/cmd.py | 62 +++++++++++++------------- examples/utils/generator/generator.dpt | 59 +++++++++--------------- 2 files changed, 52 insertions(+), 69 deletions(-) diff --git a/examples/utils/generator/cmd.py b/examples/utils/generator/cmd.py index dee34122..20c2a0da 100755 --- a/examples/utils/generator/cmd.py +++ b/examples/utils/generator/cmd.py @@ -1,14 +1,16 @@ #!/usr/bin/env python3 import sys, time, random, socket, os, struct, json, copy -from dataclasses import dataclass import binascii import dpkt from collections import namedtuple from scapy.all import sendp, Raw, Ether, sniff from threading import Thread +# the interface of the +# dataplane from the management cpu iface = "ens1" +# iface = "enp5s0" # event defs @@ -16,8 +18,6 @@ evnums = { "send_pkt": 1, "query": 3, - "start_flow": 5, - "stop_flow": 6, } def rawtime_to_us(rawtime): @@ -35,37 +35,32 @@ def rawtime_pps(start, end, pktct): def handle_report(raw_ev): - reqid, txct, rxct, tx_start, tx_end, rx_start, rx_end = struct.unpack('!IIIIIII', raw_ev[:28]) - print(f"reqid = {reqid}") - print(f"tx ct = {txct} rx ct = {rxct}") + port, reqid, txct, rxct, tx_start, tx_end, rx_start, rx_end = struct.unpack('!HIIIIIII', raw_ev[:30]) + tx_dur_us = rawtime_to_us(tx_end) - rawtime_to_us(tx_start) + rx_dur_us = rawtime_to_us(rx_end) - rawtime_to_us(rx_start) rx_rate = rawtime_pps(rx_start, rx_end, rxct) tx_rate = rawtime_pps(tx_start, tx_end, txct) - print(f"rx rate (pps) = {rx_rate} tx rate (pps) = {tx_rate}") + print("port = %s" % port) + print("reqid = %s" % reqid) + print("tx ct = %s rx ct = %s" % (txct, rxct)) + print("tx dur (us) = %s rx dur (us) = %s" % (tx_dur_us, rx_dur_us)) + print("rx rate (pps) = %s tx rate (pps) = %s" % (rx_rate, tx_rate)) if rxct > 0: loss = 1.0 - (float(rxct) / float(txct)) - print(f"loss = {loss}") - -def send_pkt(ct, src="00:11:22:33:44:55", dst="07:08:09:10:11:12", et="08:00", data="bb:aa:dd:aa:ff"): - print(f"generating command to send {ct} packets") + print("loss = %s" % loss) + +def send_pkt(port, ct, src="00:11:22:33:44:55", dst="07:08:09:10:11:12", et="08:00", data="bb:aa:dd:aa:ff"): + print("generating command to send %s packets" % ct) ct_bytes = unbbytes(ct.to_bytes(2, byteorder='big')) - port = 148 port_bytes = unbbytes(port.to_bytes(2, byteorder='big')) # send packet is event number 1 return (evnums["send_pkt"], [port_bytes, ct_bytes, dst, src, et, data]) -def query(reqid): +def query(port, reqid): reqid_bytes = unbbytes(reqid.to_bytes(4, byteorder='big')) + port_bytes = unbbytes(port.to_bytes(2, byteorder='big')) # query is event number 3 - return (evnums["query"], [reqid_bytes]) - -def start_flow(flow_id, max_pkts, src="00:11:22:33:44:55", dst="07:08:09:10:11:12", et="08:00", data="bb:aa:dd:aa:ff"): - flow_id_bytes = unbbytes(flow_id.to_bytes(1, byteorder='big')) - max_pkts_bytes = unbbytes(max_pkts.to_bytes(4, byteorder='big')) - return (evnums["start_flow"], [flow_id_bytes, max_pkts_bytes, dst, src, et, data]) - -def stop_flow(flow_id): - flow_id_bytes = unbbytes(flow_id.to_bytes(1, byteorder='big')) - return (evnums["stop_flow"], [flow_id_bytes]) + return (evnums["query"], [port_bytes, reqid_bytes]) def main(): interface = iface @@ -74,14 +69,15 @@ def main(): sys.exit(1) cmd = sys.argv[1] if cmd == "send": - if (len(sys.argv) > 2): - generate_port(interface, send_pkt(int(sys.argv[2]))) + if (len(sys.argv) == 4): + # send + generate_port(interface, send_pkt(int(sys.argv[2]), int(sys.argv[3]))) + elif (len(sys.argv) == 3): + # send + generate_port(interface, send_pkt(int(sys.argv[2]), 1)) else: - generate_port(interface, send_pkt(1)) - elif cmd == "start": - generate_port(interface, start_flow(1, (2^32)-1)) - elif cmd == "stop": - generate_port(interface, stop_flow(1)) + # send + generate_port(interface, send_pkt(148, 1)) elif cmd == "query": global handlers global stop @@ -89,7 +85,11 @@ def main(): handlers["00:02"] = handle_report handle_port(interface) time.sleep(2) - generate_port(interface, query(4)) + if (len(sys.argv) == 3): + # query + generate_port(interface, query(int(sys.argv[2]), 0)) + else: + generate_port(interface, query(148, 0)) time.sleep(2) stop = True else: diff --git a/examples/utils/generator/generator.dpt b/examples/utils/generator/generator.dpt index 67389b82..6ff7a8c4 100644 --- a/examples/utils/generator/generator.dpt +++ b/examples/utils/generator/generator.dpt @@ -1,14 +1,13 @@ // a packet generator -const int<9> server_port = 148; // command events from controller // start generating a flow of ct ethernet packets event start_flow@1(int<16> port, int<16> ct, int<48> dst, int<48> src, int<16> ety, Payload.t pl); // ask for a report about flow stats, id is query id -event send_report@3(int id); +event send_report@3(int<16> port, int id); // the report back to the controller -event report@2(int id, int txct, int rxct, int txstart, int txend, int rxstart, int rxend){skip;} +event report@2(int<16> port, int id, int txct, int rxct, int txstart, int txend, int rxstart, int rxend){skip;} // ethernet packet to / from the server packet event eth(int<48> dst, int<48> src, int<16> ety, Payload.t pl); @@ -18,7 +17,6 @@ event send_pkt@11(int<16> port, int<16> ct, int<48> dst, int<48> src, int<16> et /**** program state ****/ // time is in units of 2^16 nanoseconds, or 64 microseconds. global Array.t<32> txct = Array.create(256); -global Array.t<16> debug = Array.create(1024); global Array.t<32> tx_start = Array.create(256); global Array.t<32> tx_end = Array.create(256); @@ -53,59 +51,44 @@ handle start_flow(int<16> port, int<16> ct, int<48> dst, int<48> src, int<16> et } -/* -Insane behavior: - - scenario: start_flow(148, 2, ...) - - expected behavior: send_pkt(148, 2, ...) is called twice - - txct[148] ends at 2 - - debug[148] ends at 2 - - 2 packets get sent to server - - observed behavior: - - txct[148] ends at 3 - - debug[148] ends at 2 - - 0 packets get sent to server -*/ handle send_pkt(int<16> port, int<16> ct, int<48> dst, int<48> src, int<16> ety, Payload.t pl) { - int port_cpy = hash<32>(0, port); + int<16> port_cpy = hash<16>(0, port); int tx_ct = Array.update(txct, port, incr, 1, incr, 1); - // Array.setm(txct, port, incr, 1); - Array.setm(debug, port, incr_16, 1); - // if (tx_ct == 1) { - // Array.set(tx_start, port, Sys.time()); - // } + if (tx_ct == 1) { + Array.set(tx_start, port, Sys.time()); + } Array.set(tx_end, port, Sys.time()); // send packet to server - generate_port(server_port, eth(dst, src, ety, pl)); + generate_port((int<9>)port_cpy, eth(dst, src, ety, pl)); // if count is not 1, generate another packet if (ct != 1) { generate(send_pkt(port, ct - 1, dst, src, ety, pl)); } } -handle send_report(int id) { - int tx = Array.get(txct, server_port); - int txs = Array.get(tx_start, server_port); - int txe = Array.get(tx_end, server_port); - int rx = Array.get(rxct, server_port); - int rxs = Array.get(rx_start, server_port); - int rxe = Array.get(rx_end, server_port); - generate_port(ingress_port, report(id, tx, rx, txs, txe, rxs, rxe)); +handle send_report(int<16> port, int id) { + int tx = Array.get(txct, port); + int txs = Array.get(tx_start, port); + int txe = Array.get(tx_end, port); + int rx = Array.get(rxct, port); + int rxs = Array.get(rx_start, port); + int rxe = Array.get(rx_end, port); + generate_port(ingress_port, report(port, id, tx, rx, txs, txe, rxs, rxe)); } handle eth(int<48> dst, int<48> src, int<16> ety, Payload.t pl) { - if (ingress_port == server_port) { - int rx_ct = Array.update(rxct, server_port, incr, 1, incr, 1); - if (rx_ct == 1) { - Array.set(rx_start, server_port, Sys.time()); - } - Array.set(rx_end, server_port, Sys.time()); + int<16> port = hash<16>(0, ingress_port); + int rx_ct = Array.update(rxct, port, incr, 1, incr, 1); + if (rx_ct == 1) { + Array.set(rx_start, port, Sys.time()); } + Array.set(rx_end, port, Sys.time()); } - +// const int<9> server_port = 148; // // infinite flow events // event start_flow@5(int<8> flow_id, int<32> max_pkts, int<48>dst, int<48> src, int<16> ety, Payload.t pl); // event stop_flow@6(int<8> flow_id);