Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a repr(C) flow ID to reduce repeated per-packet conversion costs #475

Merged
merged 20 commits into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions crates/opte-api/src/ip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ impl FromStr for IpAddr {
PartialOrd,
Serialize,
)]
#[repr(C)]
pub struct Ipv4Addr {
inner: [u8; 4],
}
Expand Down Expand Up @@ -554,6 +555,7 @@ impl Deref for Ipv4Addr {
Serialize,
Deserialize,
)]
#[repr(C)]
pub struct Ipv6Addr {
inner: [u8; 16],
}
Expand Down
2 changes: 1 addition & 1 deletion crates/opte-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub use ulp::*;
///
/// We rely on CI and the check-api-version.sh script to verify that
/// this number is incremented anytime the oxide-api code changes.
pub const API_VERSION: u64 = 28;
pub const API_VERSION: u64 = 29;

/// Major version of the OPTE package.
pub const MAJOR_VERSION: u64 = 0;
Expand Down
19 changes: 11 additions & 8 deletions dtrace/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,32 @@
#define FLOW_FMT(svar, fvar) \
this->src_ip = (ipaddr_t *)alloca(4); \
this->dst_ip = (ipaddr_t *)alloca(4); \
*this->src_ip = fvar->src_ip4; \
*this->dst_ip = fvar->dst_ip4; \
*this->src_ip = fvar->addrs.ip4[0]; \
*this->dst_ip = fvar->addrs.ip4[1]; \
svar = protos[fvar->proto]; \
svar = strjoin(svar, ","); \
svar = strjoin(svar, inet_ntoa(this->src_ip)); \
svar = strjoin(svar, ":"); \
svar = strjoin(svar, lltostr(ntohs(fvar->src_port))); \
svar = strjoin(svar, lltostr(fvar->src_port)); \
svar = strjoin(svar, ","); \
svar = strjoin(svar, inet_ntoa(this->dst_ip)); \
svar = strjoin(svar, ":"); \
svar = strjoin(svar, lltostr(ntohs(fvar->dst_port)));
svar = strjoin(svar, lltostr(fvar->dst_port));

#define FLOW_FMT6(svar, fvar) \
this->src_ip6 = (in6_addr_t *)alloca(16); \
this->dst_ip6 = (in6_addr_t *)alloca(16); \
*this->src_ip6 = fvar->src_ip6; \
*this->dst_ip6 = fvar->dst_ip6; \
*this->src_ip6 = fvar->addrs.ip6[0]; \
*this->dst_ip6 = fvar->addrs.ip6[1]; \
svar = protos[fvar->proto]; \
svar = strjoin(svar, ",["); \
svar = strjoin(svar, inet_ntoa6(this->src_ip6)); \
svar = strjoin(svar, "]:"); \
svar = strjoin(svar, lltostr(ntohs(fvar->src_port))); \
svar = strjoin(svar, lltostr(fvar->src_port)); \
svar = strjoin(svar, ",["); \
svar = strjoin(svar, inet_ntoa6(this->dst_ip6)); \
svar = strjoin(svar, "]:"); \
svar = strjoin(svar, lltostr(ntohs(fvar->dst_port)));
svar = strjoin(svar, lltostr(fvar->dst_port));

#define ETH_FMT(svar, evar) \
svar = substr(lltostr(evar[0], 16), 2); \
Expand All @@ -55,3 +55,6 @@
* 2 = Outbound
*/
#define DIR_STR(dir) ((dir) == 1 ? "IN" : "OUT")

#define EL_DELIMIT "->"
#define EL_FMT "->%s"
12 changes: 6 additions & 6 deletions dtrace/lib/common.d
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
#pragma D depends_on provider ip

typedef struct flow_id_sdt_arg {
int af;
ipaddr_t src_ip4;
ipaddr_t dst_ip4;
in6_addr_t src_ip6;
in6_addr_t dst_ip6;
uint8_t proto;
uint16_t af;
FelixMcFelix marked this conversation as resolved.
Show resolved Hide resolved
union addrs {
ipaddr_t ip4[2];
in6_addr_t ip6[2];
FelixMcFelix marked this conversation as resolved.
Show resolved Hide resolved
} addrs;
uint16_t src_port;
uint16_t dst_port;
uint8_t proto;
} flow_id_sdt_arg_t;

typedef struct rule_match_sdt_arg {
Expand Down
33 changes: 21 additions & 12 deletions dtrace/opte-bad-packet.d
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
#include "common.h"

#define HDR_FMT "%-12s %-3s %-18s %s\n"
#define LINE_FMT "%-12s %-3s 0x%-16p "
#define EL_FMT "->%s"
#define LINE_FMT "%-12s %-3s 0x%-16p %s[%d, %d]\n"

BEGIN {
printf(HDR_FMT, "PORT", "DIR", "MBLK", "MSG+DATA");
Expand All @@ -21,13 +20,13 @@ bad-packet {
this->msgs = (derror_sdt_arg_t*) arg3;
this->msg_len = this->msgs->len;
this->data_len = arg4;
this->res = stringof("");

if (num >= 10) {
printf(HDR_FMT, "PORT", "DIR", "MBLK", "MSG+DATA");
num = 0;
}

printf(LINE_FMT, this->port, this->dir, this->mblk);
num++;
}

Expand All @@ -36,51 +35,61 @@ bad-packet {
bad-packet
/this->msg_len > 0/
{
printf("%s", stringof(this->msgs->entry[0]));
this->res = strjoin(this->res, stringof(this->msgs->entry[0]));
}

bad-packet
/this->msg_len > 1/
{
printf(EL_FMT, stringof(this->msgs->entry[1]));
this->res = strjoin(this->res, EL_DELIMIT);
this->res = strjoin(this->res, stringof(this->msgs->entry[1]));
}

bad-packet
/this->msg_len > 2/
{
printf(EL_FMT, stringof(this->msgs->entry[2]));
this->res = strjoin(this->res, EL_DELIMIT);
this->res = strjoin(this->res, stringof(this->msgs->entry[2]));
}

bad-packet
/this->msg_len > 3/
{
printf(EL_FMT, stringof(this->msgs->entry[3]));
this->res = strjoin(this->res, EL_DELIMIT);
this->res = strjoin(this->res, stringof(this->msgs->entry[3]));
}

bad-packet
/this->msg_len > 4/
{
printf(EL_FMT, stringof(this->msgs->entry[4]));
this->res = strjoin(this->res, EL_DELIMIT);
this->res = strjoin(this->res, stringof(this->msgs->entry[4]));
}

bad-packet
/this->msg_len > 5/
{
printf(EL_FMT, stringof(this->msgs->entry[5]));
this->res = strjoin(this->res, EL_DELIMIT);
this->res = strjoin(this->res, stringof(this->msgs->entry[5]));
}

bad-packet
/this->msg_len > 6/
{
printf(EL_FMT, stringof(this->msgs->entry[6]));
this->res = strjoin(this->res, EL_DELIMIT);
this->res = strjoin(this->res, stringof(this->msgs->entry[6]));
}

bad-packet
/this->msg_len > 7/
{
printf(EL_FMT, stringof(this->msgs->entry[7]));
this->res = strjoin(this->res, EL_DELIMIT);
this->res = strjoin(this->res, stringof(this->msgs->entry[7]));
}

bad-packet {
printf(" [%d, %d]\n", this->msgs->data[0], this->msgs->data[1]);
printf(LINE_FMT,
this->port, this->dir, this->mblk,
this->res, this->msgs->data[0], this->msgs->data[1]
);
}
17 changes: 16 additions & 1 deletion dtrace/opte-layer-process.d
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ layer-process-return {
this->layer = stringof(arg2);
this->flow_before = (flow_id_sdt_arg_t *)arg3;
this->flow_after = (flow_id_sdt_arg_t *)arg4;
this->res = stringof(arg5);
this->msgs = (derror_sdt_arg_t*) arg5;
this->msg_len = this->msgs->len;
this->res = stringof("");

if (num >= 10) {
printf(HDR_FMT, "PORT", "LAYER", "DIR", "FLOW BEFORE",
Expand All @@ -38,6 +40,19 @@ layer-process-return {
}
}

layer-process-return
/this->msg_len > 0/
{
this->res = strjoin(this->res, stringof(this->msgs->entry[0]));
}

layer-process-return
/this->msg_len > 1/
{
this->res = strjoin(this->res, EL_DELIMIT);
this->res = strjoin(this->res, stringof(this->msgs->entry[1]));
}

layer-process-return /this->af == AF_INET/ {
FLOW_FMT(this->s_before, this->flow_before);
FLOW_FMT(this->s_after, this->flow_after);
Expand Down
18 changes: 16 additions & 2 deletions dtrace/opte-port-process.d
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ port-process-return {
this->mp = (mblk_t *)arg5;
/* If the result is a hairpin packet, then hp_mp is non-NULL. */
this->hp_mp = (mblk_t *)arg6;
this->res = stringof(arg7);
this->msgs = (derror_sdt_arg_t*) arg7;
this->msg_len = this->msgs->len;
this->res = stringof("");

if (num >= 10) {
printf(HDR_FMT, "NAME", "DIR", "EPOCH", "FLOW BEFORE",
Expand All @@ -39,6 +41,19 @@ port-process-return {
}
}

port-process-return
/this->msg_len > 0/
{
this->res = strjoin(this->res, stringof(this->msgs->entry[0]));
}

port-process-return
/this->msg_len > 1/
{
this->res = strjoin(this->res, EL_DELIMIT);
this->res = strjoin(this->res, stringof(this->msgs->entry[1]));
}

port-process-return /this->af == AF_INET/ {
FLOW_FMT(this->s_before, this->flow_before);
FLOW_FMT(this->s_after, this->flow_after);
Expand All @@ -55,4 +70,3 @@ port-process-return /this->af == AF_INET6/ {
num++;
}


37 changes: 18 additions & 19 deletions lib/opte/src/engine/flow_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,12 @@ use alloc::string::String;
use alloc::vec::Vec;
use core::fmt;
use core::num::NonZeroU32;
#[cfg(all(not(feature = "std"), not(test)))]
use illumos_sys_hdrs::uintptr_t;
use opte_api::OpteError;
use serde::de::DeserializeOwned;
use serde::Serialize;

cfg_if! {
if #[cfg(all(not(feature = "std"), not(test)))] {
use illumos_sys_hdrs::uintptr_t;
use super::rule::flow_id_sdt_arg;
}
}

// XXX This really shouldn't be pub but for now we are leaking this
// info for the purpose of testing until the Port API has support for
// setting/getting TTL on a per Flow Table basis.
Expand Down Expand Up @@ -229,16 +224,15 @@ fn flow_expired_probe(
last_hit: Option<Moment>,
now: Option<Moment>,
) {
let a = crate::NopDrop;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All NopDrop code will be removed once illumos#16480 is merged in and available on the helios-2.0 lab image.

last_hit.unwrap_or_default();
cfg_if! {
if #[cfg(all(not(feature = "std"), not(test)))] {
let arg = flow_id_sdt_arg::from(flowid);

unsafe {
__dtrace_probe_flow__expired(
port.as_ptr() as uintptr_t,
name.as_ptr() as uintptr_t,
&arg as *const flow_id_sdt_arg as uintptr_t,
flowid,
last_hit.and_then(|m| m.raw_millis()).unwrap_or_default() as usize,
now.and_then(|m| m.raw_millis()).unwrap_or_default() as usize,
);
Expand All @@ -254,6 +248,7 @@ fn flow_expired_probe(
let (_, _, _) = (port, name, flowid);
}
}
drop(a);
}

/// A type that can be "dumped" for the purposes of presenting an
Expand Down Expand Up @@ -332,7 +327,7 @@ extern "C" {
pub fn __dtrace_probe_flow__expired(
port: uintptr_t,
layer: uintptr_t,
flowid: uintptr_t,
flowid: *const InnerFlowId,
last_hit: uintptr_t,
now: uintptr_t,
);
Expand All @@ -341,7 +336,7 @@ extern "C" {
dir: uintptr_t,
port: uintptr_t,
layer: uintptr_t,
ifid: uintptr_t,
ifid: *const InnerFlowId,
epoch: uintptr_t,
);
}
Expand All @@ -355,8 +350,8 @@ impl Dump for () {
#[cfg(test)]
mod test {
use super::*;
use crate::engine::headers::IpAddr;
use crate::engine::ip4::Protocol;
use crate::engine::packet::AddrPair;
use crate::engine::packet::FLOW_ID_DEFAULT;
use core::time::Duration;

Expand All @@ -365,10 +360,12 @@ mod test {
#[test]
fn flow_expired() {
let flowid = InnerFlowId {
proto: Protocol::TCP,
src_ip: IpAddr::Ip4("192.168.2.10".parse().unwrap()),
proto: Protocol::TCP.into(),
addrs: AddrPair::V4 {
src: "192.168.2.10".parse().unwrap(),
dst: "76.76.21.21".parse().unwrap(),
},
src_port: 37890,
dst_ip: IpAddr::Ip4("76.76.21.21".parse().unwrap()),
dst_port: 443,
};

Expand All @@ -389,10 +386,12 @@ mod test {
#[test]
fn flow_clear() {
let flowid = InnerFlowId {
proto: Protocol::TCP,
src_ip: IpAddr::Ip4("192.168.2.10".parse().unwrap()),
proto: Protocol::TCP.into(),
addrs: AddrPair::V4 {
src: "192.168.2.10".parse().unwrap(),
dst: "76.76.21.21".parse().unwrap(),
},
src_port: 37890,
dst_ip: IpAddr::Ip4("76.76.21.21".parse().unwrap()),
dst_port: 443,
};

Expand Down
Loading