Skip to content

Commit 70785d9

Browse files
committed
add ability to set all firewall rules atomically (#143)
Need UFT invalidation on layer/rule changes (#21)
1 parent b998015 commit 70785d9

File tree

20 files changed

+713
-223
lines changed

20 files changed

+713
-223
lines changed

dtrace/opte-port-process.d

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
*/
66
#include "common.h"
77

8-
#define HDR_FMT "%-12s %-3s %-43s %-18s %s\n"
9-
#define LINE_FMT "%-12s %-3s %-43s 0x%-16p %s\n"
8+
#define HDR_FMT "%-12s %-3s %-8s %-43s %-18s %s\n"
9+
#define LINE_FMT "%-12s %-3s %-8u %-43s 0x%-16p %s\n"
1010

1111
BEGIN {
1212
/*
@@ -18,19 +18,21 @@ BEGIN {
1818
protos[17] = "UDP";
1919
protos[255] = "XXX";
2020

21-
printf(HDR_FMT, "NAME", "DIR", "FLOW", "MBLK", "RESULT");
21+
printf(HDR_FMT, "NAME", "DIR", "EPOCH", "FLOW", "MBLK", "RESULT");
2222
num = 0;
2323
}
2424

2525
port-process-return {
2626
this->dir = stringof(arg0);
2727
this->name = stringof(arg1);
2828
this->flow = (flow_id_sdt_arg_t *)arg2;
29-
this->mp = arg3;
30-
this->res = stringof(arg4);
29+
this->epoch = arg3;
30+
this->mp = arg4;
31+
this->res = stringof(arg5);
3132

3233
if (num >= 10) {
33-
printf(HDR_FMT, "NAME", "DIR", "FLOW", "MBLK", "RESULT");
34+
printf(HDR_FMT, "NAME", "DIR", "EPOCH", "FLOW", "MBLK",
35+
"RESULT");
3436
num = 0;
3537
}
3638

@@ -43,13 +45,15 @@ port-process-return {
4345

4446
port-process-return /this->af == AF_INET/ {
4547
FLOW_FMT(this->s, this->flow);
46-
printf(LINE_FMT, this->name, this->dir, this->s, this->mp, this->res);
48+
printf(LINE_FMT, this->name, this->dir, this->epoch, this->s, this->mp,
49+
this->res);
4750
num++;
4851
}
4952

5053
port-process-return /this->af == AF_INET6/ {
5154
FLOW_FMT6(this->s, this->flow);
52-
printf(LINE_FMT, this->name, this->dir, this->s, this->mp, this->res);
55+
printf(LINE_FMT, this->name, this->dir, this->epoch, this->s, this->mp,
56+
this->res);
5357
num++;
5458
}
5559

dtrace/opte-uft-invaildate.d

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Track UFT entry invalidations as they happen. An invalidation
3+
* occurs when the port's epoch has move forward based on a rule
4+
* change but the UFT entry is based on an older epoch; therefore it
5+
* needs to be invalidated so that a new entry may be generated from
6+
* the current rule set.
7+
*
8+
* dtrace -L ./lib -I . -Cqs ./opte-uft-invalidate.d
9+
*/
10+
#include "common.h"
11+
12+
#define HDR_FMT "%-8s %-3s %-43s %s\n"
13+
#define LINE_FMT "%-8s %-3s %-43s %u\n"
14+
15+
BEGIN {
16+
/*
17+
* Use an associative array to stringify the protocol number.
18+
*/
19+
protos[1] = "ICMP";
20+
protos[2] = "IGMP";
21+
protos[6] = "TCP";
22+
protos[17] = "UDP";
23+
protos[255] = "XXX";
24+
25+
printf(HDR_FMT, "PORT", "DIR", "FLOW", "EPOCH");
26+
num = 0;
27+
}
28+
29+
flow-entry-invalidated {
30+
this->dir = stringof(arg0);
31+
this->port = stringof(arg1);
32+
this->flow = (flow_id_sdt_arg_t *)arg2;
33+
this->epoch = arg3;
34+
this->af = this->flow->af;
35+
36+
if (num >= 10) {
37+
printf(HDR_FMT, "PORT", "DIR", "FLOW", "EPOCH");
38+
num = 0;
39+
}
40+
41+
if (this->af != AF_INET && this->af != AF_INET6) {
42+
printf("BAD ADDRESS FAMILY: %d\n", this->af);
43+
}
44+
}
45+
46+
ft-entry-invliadated /this->af == AF_INET/ {
47+
FLOW_FMT(this->s, this->flow);
48+
printf(LINE_FMT, this->dir, this->port, this->s, this->epoch);
49+
num++;
50+
}
51+
52+
ft-entry-invliadated /this->af == AF_INET6/ {
53+
FLOW_FMT6(this->s, this->flow);
54+
printf(LINE_FMT, this->dir, this->port, this->s, this->epoch);
55+
num++;
56+
}
57+

dtrace/usdt-port-process.d

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
1-
#define HDR_FMT "%-3s %-12s %-43s 0x%-16s %s\n"
2-
#define LINE_FMT "%-3s %-12s %-43s 0x%-16p %s\n"
1+
#define HDR_FMT "%-3s %-12s %-8s %-43s %-18s %s\n"
2+
#define LINE_FMT "%-3s %-12s %-8u %-43s 0x%-16p %s\n"
33

44
BEGIN {
5-
printf(HDR_FMT, "DIR", "NAME", "FLOW", "MBLK", "RESULT");
5+
printf(HDR_FMT, "DIR", "NAME", "EPOCH", "FLOW", "MBLK", "RESULT");
66
num = 0;
77
}
88

99
port-process-return {
1010
this->dir = json(copyinstr(arg0), "ok");
1111
this->name = copyinstr(arg1);
1212
this->flow = copyinstr(arg2);
13-
this->mp = arg3;
14-
this->res = copyinstr(arg4);
13+
this->epoch = arg3;
14+
this->mp = arg4;
15+
this->res = copyinstr(arg5);
1516
num++;
1617

1718
if (num >= 10) {
18-
printf(HDR_FMT, "DIR", "NAME", "FLOW", "MBLK", "RESULT");
19+
printf(HDR_FMT, "DIR", "NAME", "EPCOH", "FLOW", "MBLK",
20+
"RESULT");
1921
num = 0;
2022
}
2123

22-
printf(LINE_FMT, this->dir, this->name, this->flow, this->mp, this->res);
23-
}
24+
printf(LINE_FMT, this->dir, this->name, this->epoch, this->flow,
25+
this->mp, this->res);
26+
}

dtrace/usdt-uft-invalidate.d

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#define HDR_FMT "%-8s %-3s %-43s %s\n"
2+
#define LINE_FMT "%-8s %-3s %-43s %u\n"
3+
4+
BEGIN {
5+
printf(HDR_FMT, "PORT", "DIR", "FLOW", "EPOCH");
6+
num = 0;
7+
}
8+
9+
uft-invalidate {
10+
this->dir = json(copyinstr(arg0), "ok");
11+
this->port = copyinstr(arg1);
12+
this->flow = copyinstr(arg2);
13+
this->epoch = arg3;
14+
num++;
15+
16+
if (num >= 10) {
17+
printf(HDR_FMT, "PORT", "DIR", "FLOW", "EPOCH");
18+
num = 0;
19+
}
20+
21+
printf(LINE_FMT, this->port, this->dir, this->flow, this->epoch);
22+
}

opte-ioctl/src/lib.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use opte::api::{
1010
};
1111
use opte::oxide_vpc::api::{
1212
AddRouterEntryIpv4Req, CreateXdeReq, DeleteXdeReq, ListPortsReq,
13-
ListPortsResp, SetVirt2PhysReq,
13+
ListPortsResp, SetFwRulesReq, SetVirt2PhysReq,
1414
};
1515
use serde::de::DeserializeOwned;
1616
use serde::Serialize;
@@ -165,6 +165,11 @@ impl OpteHdl {
165165
let cmd = OpteCmd::AddRouterEntryIpv4;
166166
run_cmd_ioctl(self.device.as_raw_fd(), cmd, &req)
167167
}
168+
169+
pub fn set_fw_rules(&self, req: &SetFwRulesReq) -> Result<NoResp, Error> {
170+
let cmd = OpteCmd::SetFwRules;
171+
run_cmd_ioctl(self.device.as_raw_fd(), cmd, &req)
172+
}
168173
}
169174

170175
#[cfg(target_os = "illumos")]

opte/Cargo.lock

Lines changed: 22 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

opte/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ postcard = { version = "0.7.0", features = ["alloc"], default-features = false }
3030
#
3131
# cargo test --features=usdt
3232
#
33-
usdt = { version = "*", optional = true }
33+
usdt = { version = "0.3.2", optional = true }
3434
zerocopy = "0.6.1"
3535

3636
#
@@ -62,4 +62,5 @@ default-features = false
6262
features = ["alloc", "medium-ethernet", "proto-ipv4", "proto-ipv6", "proto-dhcpv4", "socket", "socket-raw"]
6363

6464
[dev-dependencies]
65+
ctor = "0.1.22"
6566
pcap-parser = { version = "0.11.1", features = ["serialize"] }

opte/src/api/cmd.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub enum OpteCmd {
2525
ListPorts = 1, // list all ports
2626
AddFwRule = 20, // add firewall rule
2727
RemFwRule = 21, // remove firewall rule
28+
SetFwRules = 22, // set/replace all firewall rules at once
2829
DumpTcpFlows = 30, // dump TCP flows
2930
DumpLayer = 31, // dump the specified Layer
3031
DumpUft = 32, // dump the Unified Flow Table
@@ -46,6 +47,7 @@ impl TryFrom<c_int> for OpteCmd {
4647
1 => Ok(Self::ListPorts),
4748
20 => Ok(Self::AddFwRule),
4849
21 => Ok(Self::RemFwRule),
50+
22 => Ok(Self::SetFwRules),
4951
30 => Ok(Self::DumpTcpFlows),
5052
31 => Ok(Self::DumpLayer),
5153
32 => Ok(Self::DumpUft),

opte/src/engine/flow_table.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ where
9191
let entry = FlowEntry::new(state);
9292
match self.map.insert(flow_id.clone(), entry) {
9393
None => Ok(()),
94-
Some(_) => return Err(OpteError::FlowExists(flow_id.to_string())),
94+
Some(_) => Err(OpteError::FlowExists(flow_id.to_string())),
9595
}
9696
}
9797

@@ -158,6 +158,10 @@ where
158158
self.map.len() as u32
159159
}
160160

161+
pub fn remove(&mut self, flow: &InnerFlowId) -> Option<FlowEntry<S>> {
162+
self.map.remove(flow)
163+
}
164+
161165
pub fn ttl(&self) -> Ttl {
162166
self.ttl
163167
}
@@ -176,8 +180,6 @@ fn flow_expired_probe(port: &CString, name: &CString, flowid: &InnerFlowId) {
176180
);
177181
}
178182
} else if #[cfg(feature = "usdt")] {
179-
use std::arch::asm;
180-
181183
let port_s = port.to_str().unwrap();
182184
let name_s = name.to_str().unwrap();
183185
crate::opte_provider::flow__expired!(
@@ -256,6 +258,14 @@ extern "C" {
256258
layer: uintptr_t,
257259
flowid: uintptr_t,
258260
);
261+
262+
pub fn __dtrace_probe_ft__entry__invalidated(
263+
dir: uintptr_t,
264+
port: uintptr_t,
265+
layer: uintptr_t,
266+
ifid: uintptr_t,
267+
epoch: uintptr_t,
268+
);
259269
}
260270

261271
impl StateSummary for () {

0 commit comments

Comments
 (0)