Skip to content

Commit

Permalink
Fix bug that ARP replies are generated in ANALYZE mode
Browse files Browse the repository at this point in the history
  • Loading branch information
NE4Y committed Mar 15, 2024
1 parent 806b796 commit 7bce638
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- Increase meter entries & register entries to 512 to be able to use ports with PID > 255
- Bug in analyze mode that returned an error when no streams / stream settings were provided
- Preliminary import/export function for settings
- Fix bug that prevents that ARP replies are always generated in ANALYZE mode

## v2.2.0
- Added VxLAN support
Expand Down
18 changes: 17 additions & 1 deletion Controller/src/core/traffic_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,9 @@ impl TrafficGen {
state.frame_type_monitor.lock().await.on_start(switch, &mode).await?;
state.rate_monitor.lock().await.on_start(switch, &mode).await?;

// configure tg mode
self.configure_traffic_gen_mode_table(switch, &mode).await?;

// configure default forwarding
// this pushes rules for RX -> RX Recirc and TX Recirc -> TX
self.configure_default_forwarding_path(switch, &state.port_mapping).await?;
Expand Down Expand Up @@ -782,9 +785,22 @@ impl TrafficGen {
Ok(app_to_offset)
}

/// Configures the traffic gen mode table in the data plane
/// that is used to detect the generation mode
async fn configure_traffic_gen_mode_table(&self, switch: &SwitchConnection, mode: &GenerationMode) -> Result<(), RBFRTError> {
let req = Request::new(TRAFFIC_GEN_MODE)
.match_key("ig_intr_md.ingress_port", MatchValue::lpm(0, 0))
.action("ingress.set_mode")
.action_data("mode", *mode as u8);

switch.write_table_entry(req).await?;

Ok(())
}

/// Clears various tables that are refilled during traffic gen setup
async fn reset_tables(&self, switch: &SwitchConnection) -> Result<(), RBFRTError> {
switch.clear_tables(vec![IS_EGRESS_TABLE, IS_TX_EGRESS_TABLE, VLAN_HEADER_REPLACE_TABLE, MPLS_HEADER_REPLACE_TABLE, ETHERNET_IP_HEADER_REPLACE_TABLE, DEFAULT_FORWARD_TABLE]).await?;
switch.clear_tables(vec![TRAFFIC_GEN_MODE, IS_EGRESS_TABLE, IS_TX_EGRESS_TABLE, VLAN_HEADER_REPLACE_TABLE, MPLS_HEADER_REPLACE_TABLE, ETHERNET_IP_HEADER_REPLACE_TABLE, DEFAULT_FORWARD_TABLE]).await?;

Ok(())
}
Expand Down
3 changes: 3 additions & 0 deletions Controller/src/core/traffic_gen_core/const_definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ pub const MONITORING_FORWARD_TABLE: &str = "ingress.p4tg.monitor_forward";
/// Triggers monitoring in egress for individual streams
pub const MONITORING_EGRESS_TABLE: &str = "egress.monitor_stream";

/// Indicates the current generation type
pub const TRAFFIC_GEN_MODE: &str = "ingress.tg_mode";

/// Table that indicates that a packet is on a front panel egress port.
/// If thats the case, the packet is timestamped for RTT calculation.
pub const IS_EGRESS_TABLE: &str = "egress.is_egress";
Expand Down
3 changes: 3 additions & 0 deletions P4-Implementation/src/headers.p4
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ const bit<8> IP_PROTOCOL_P4TG = 110;
const bit<16> UDP_VxLAN_PORT = 4789;
const bit<16> UDP_P4TG_PORT = 50083;

const bit<8> TG_MODE_ANALYZE = 4;



header ethernet_h {
Expand Down Expand Up @@ -192,6 +194,7 @@ struct ingress_metadata_t {
PortId_t ig_port;
bit<1> vxlan;
bit<1> arp_reply;
bit<8> tg_mode;
}

struct egress_metadata_t {
Expand Down
16 changes: 16 additions & 0 deletions P4-Implementation/src/ingress.p4
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,23 @@ control ingress(
P4TG_Ingress() p4tg;
ARP() arp;

action set_mode(bit<8> mode) {
ig_md.tg_mode = mode;
}

table tg_mode {
key = {
ig_intr_md.ingress_port: lpm;
}
actions = {
set_mode;
}
size = 1;
}

apply {
tg_mode.apply();

arp.apply(hdr, ig_md, ig_intr_md, ig_tm_md);
p4tg.apply(hdr, ig_md, ig_intr_md, ig_prsr_md, ig_dprsr_md, ig_tm_md);
}
Expand Down
2 changes: 1 addition & 1 deletion P4-Implementation/src/libs/ingress/ARP.p4
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ control ARP(inout header_t hdr, inout ingress_metadata_t ig_md, in ingress_intri
}

apply {
if(hdr.arp.isValid() && hdr.arp.op == 1) { // it's an arp request
if(hdr.arp.isValid() && hdr.arp.op == 1 && ig_md.tg_mode != TG_MODE_ANALYZE) { // it's an arp request
if(arp_reply.apply().hit) {
if(ig_md.arp_reply == 0) {
invalidate(ig_tm_md.ucast_egress_port);
Expand Down
1 change: 1 addition & 0 deletions P4-Implementation/src/parser.p4
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ parser SwitchIngressParser(
ig_md.iat = 0;
ig_md.rtt = 0;
ig_md.vxlan = 0;
ig_md.tg_mode = 0;
tofino_parser.apply(pkt, ig_intr_md);
transition select(ig_intr_md.ingress_port) {
68: parse_pkt_gen;
Expand Down

0 comments on commit 7bce638

Please sign in to comment.