Skip to content

Commit 9cefaeb

Browse files
committed
No LFTs yet, no expiry.
Rather a lot of plumbing
1 parent 3c2750d commit 9cefaeb

File tree

16 files changed

+384
-208
lines changed

16 files changed

+384
-208
lines changed

lib/opte-test-utils/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -269,11 +269,11 @@ fn oxide_net_builder(
269269
let dhcp = base_dhcp_config();
270270

271271
firewall::setup(&mut pb, fw_limit).expect("failed to add firewall layer");
272-
gateway::setup(&pb, cfg, vpc_map, fw_limit, &dhcp)
272+
gateway::setup(&mut pb, cfg, vpc_map, fw_limit, &dhcp)
273273
.expect("failed to setup gateway layer");
274-
router::setup(&pb, cfg, one_limit).expect("failed to add router layer");
274+
router::setup(&mut pb, cfg, one_limit).expect("failed to add router layer");
275275
nat::setup(&mut pb, cfg, snat_limit).expect("failed to add nat layer");
276-
overlay::setup(&pb, cfg, v2p, v2b, one_limit)
276+
overlay::setup(&mut pb, cfg, v2p, v2b, one_limit)
277277
.expect("failed to add overlay layer");
278278
pb
279279
}

lib/opte/src/engine/layer.rs

Lines changed: 90 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use super::packet::InnerFlowId;
1717
use super::packet::MblkFullParsed;
1818
use super::packet::MblkPacketData;
1919
use super::packet::Packet;
20+
use super::port::PortBuilder;
2021
use super::port::Transforms;
2122
use super::port::meta::ActionMeta;
2223
use super::rule;
@@ -28,6 +29,8 @@ use super::rule::GenBtError;
2829
use super::rule::HdrTransformError;
2930
use super::rule::Rule;
3031
use super::rule::ht_probe;
32+
use super::stat::StatTree;
33+
use super::stat::TableStat;
3134
use crate::ExecCtx;
3235
use crate::LogLevel;
3336
use crate::api::DumpLayerResp;
@@ -56,6 +59,7 @@ use opte_api::Direction;
5659
use opte_api::RuleDump;
5760
use opte_api::RuleId;
5861
use opte_api::RuleTableEntryDump;
62+
use uuid::Uuid;
5963

6064
#[derive(Debug)]
6165
pub enum LayerError {
@@ -353,8 +357,9 @@ pub enum EntryState {
353357
/// reasonable to open this up to be any [`Action`], if such a use
354358
/// case were to present itself. For now, we stay conservative, and
355359
/// supply only what the current consumers need.
356-
#[derive(Copy, Clone, Debug)]
360+
#[derive(Copy, Clone, Debug, Default)]
357361
pub enum DefaultAction {
362+
#[default]
358363
Allow,
359364
StatefulAllow,
360365
Deny,
@@ -407,7 +412,7 @@ impl Display for ActionDescEntry {
407412
///
408413
/// This describes the actions a layer's rules can take as well as the
409414
/// [`DefaultAction`] to take when a rule doesn't match.
410-
#[derive(Debug)]
415+
#[derive(Debug, Default)]
411416
pub struct LayerActions {
412417
/// The list of actions shared among the layer's rules. An action
413418
/// doesn't have to be shared, each rule is free to create its
@@ -419,9 +424,15 @@ pub struct LayerActions {
419424
/// direction.
420425
pub default_in: DefaultAction,
421426

427+
/// The stats ID to attach to the default-in action.
428+
pub default_in_stat_id: Option<Uuid>,
429+
422430
/// The default action to take if no rule matches in the outbound
423431
/// direction.
424432
pub default_out: DefaultAction,
433+
434+
/// The stats ID to attach to the default-in action.
435+
pub default_out_stat_id: Option<Uuid>,
425436
}
426437

427438
#[derive(KStatProvider)]
@@ -503,8 +514,10 @@ pub struct Layer {
503514
actions: Vec<Action>,
504515
default_in: DefaultAction,
505516
default_in_hits: u64,
517+
default_in_stat: Arc<TableStat>,
506518
default_out: DefaultAction,
507519
default_out_hits: u64,
520+
default_out_stat: Arc<TableStat>,
508521
ft: LayerFlowTable,
509522
ft_cstr: CString,
510523
rules_in: RuleTable,
@@ -518,15 +531,20 @@ impl Layer {
518531
self.actions.get(idx).cloned()
519532
}
520533

521-
pub fn add_rule(&mut self, dir: Direction, rule: Rule<Finalized>) {
534+
pub fn add_rule(
535+
&mut self,
536+
dir: Direction,
537+
rule: Rule<Finalized>,
538+
stats: &mut StatTree,
539+
) {
522540
match dir {
523541
Direction::Out => {
524-
self.rules_out.add(rule);
542+
self.rules_out.add(rule, stats);
525543
self.stats.vals.out_rules += 1;
526544
}
527545

528546
Direction::In => {
529-
self.rules_in.add(rule);
547+
self.rules_in.add(rule, stats);
530548
self.stats.vals.in_rules += 1;
531549
}
532550
}
@@ -737,18 +755,24 @@ impl Layer {
737755

738756
pub fn new(
739757
name: &'static str,
740-
port: &str,
758+
port: &mut PortBuilder,
741759
actions: LayerActions,
742760
ft_limit: NonZeroU32,
743761
) -> Self {
744-
let port_c = CString::new(port).unwrap();
762+
let stats = port.stats_mut();
763+
let default_in_stat = stats.root(actions.default_in_stat_id);
764+
let default_out_stat = stats.root(actions.default_out_stat_id);
765+
766+
let port_name = port.name();
767+
768+
let port_c = CString::new(port_name).unwrap();
745769
let name_c = CString::new(name).unwrap();
746770

747771
// Unwrap: We know this is fine because the stat names are
748772
// generated from the LayerStats structure.
749773
let stats = KStatNamed::new(
750774
"xde",
751-
&format!("{}_{}", port, name),
775+
&format!("{}_{}", port_name, name),
752776
LayerStats::new(),
753777
)
754778
.unwrap();
@@ -759,15 +783,17 @@ impl Layer {
759783
actions: actions.actions,
760784
default_in: actions.default_in,
761785
default_in_hits: 0,
786+
default_in_stat,
762787
default_out: actions.default_out,
763788
default_out_hits: 0,
789+
default_out_stat,
764790
name,
765791
name_c,
766792
port_c,
767-
ft: LayerFlowTable::new(port, name, ft_limit),
793+
ft: LayerFlowTable::new(port_name, name, ft_limit),
768794
ft_cstr: CString::new(format!("ft-{}", name)).unwrap(),
769-
rules_in: RuleTable::new(port, name, Direction::In),
770-
rules_out: RuleTable::new(port, name, Direction::Out),
795+
rules_in: RuleTable::new(port_name, name, Direction::In),
796+
rules_out: RuleTable::new(port_name, name, Direction::Out),
771797
rt_cstr: CString::new(format!("rt-{}", name)).unwrap(),
772798
stats,
773799
}
@@ -795,12 +821,12 @@ impl Layer {
795821
xforms: &mut Transforms,
796822
ameta: &mut ActionMeta,
797823
) -> result::Result<LayerResult, LayerError> {
798-
use Direction::*;
799824
let flow_before = *pkt.flow();
800825
self.layer_process_entry_probe(dir, pkt.flow());
826+
pkt.meta_mut().stats.new_layer();
801827
let res = match dir {
802-
Out => self.process_out(ectx, pkt, xforms, ameta),
803-
In => self.process_in(ectx, pkt, xforms, ameta),
828+
Direction::Out => self.process_out(ectx, pkt, xforms, ameta),
829+
Direction::In => self.process_in(ectx, pkt, xforms, ameta),
804830
};
805831
self.layer_process_return_probe(dir, &flow_before, pkt.flow(), &res);
806832
res
@@ -888,15 +914,21 @@ impl Layer {
888914
self.stats.vals.in_lft_miss += 1;
889915
let rule = self.rules_in.find_match(pkt.flow(), pkt.meta(), ameta);
890916

891-
let action = if let Some(rule) = rule {
917+
let (action, stat) = if let Some(rule) = rule {
892918
self.stats.vals.in_rule_match += 1;
893-
rule.action()
919+
(rule.rule.action(), rule.stat.clone())
894920
} else {
895921
self.stats.vals.in_rule_nomatch += 1;
896922
self.default_in_hits += 1;
897-
self.default_in.into()
923+
(self.default_in.into(), self.default_in_stat.clone())
898924
};
899925

926+
// No LFT to account for.
927+
let mut stat = Some(stat);
928+
if !matches!(action, Action::StatefulAllow | Action::Stateful(_)) {
929+
pkt.meta_mut().stats.push(stat.take().unwrap());
930+
}
931+
900932
match action {
901933
Action::Allow => Ok(LayerResult::Allow),
902934

@@ -909,6 +941,8 @@ impl Layer {
909941
});
910942
}
911943

944+
// TODO: how on earth are we plumbing StatTree into here??
945+
912946
// The outbound flow ID mirrors the inbound. Remember,
913947
// the "top" of layer represents how the client sees
914948
// the traffic, and the "bottom" of the layer
@@ -1019,6 +1053,8 @@ impl Layer {
10191053
});
10201054
}
10211055

1056+
// TODO: how on earth are we plumbing StatTree into here??
1057+
10221058
let desc = match action.gen_desc(pkt.flow(), pkt, ameta) {
10231059
Ok(aord) => match aord {
10241060
AllowOrDeny::Allow(desc) => desc,
@@ -1175,15 +1211,21 @@ impl Layer {
11751211
self.stats.vals.out_lft_miss += 1;
11761212
let rule = self.rules_out.find_match(pkt.flow(), pkt.meta(), ameta);
11771213

1178-
let action = if let Some(rule) = rule {
1214+
let (action, stat) = if let Some(rule) = rule {
11791215
self.stats.vals.out_rule_match += 1;
1180-
rule.action()
1216+
(rule.rule.action(), rule.stat.clone())
11811217
} else {
11821218
self.stats.vals.out_rule_nomatch += 1;
11831219
self.default_out_hits += 1;
1184-
self.default_out.into()
1220+
(self.default_out.into(), self.default_out_stat.clone())
11851221
};
11861222

1223+
// No LFT to account for.
1224+
let mut stat = Some(stat);
1225+
if !matches!(action, Action::StatefulAllow | Action::Stateful(_)) {
1226+
pkt.meta_mut().stats.push(stat.take().unwrap());
1227+
}
1228+
11871229
match action {
11881230
Action::Allow => Ok(LayerResult::Allow),
11891231

@@ -1196,6 +1238,8 @@ impl Layer {
11961238
});
11971239
}
11981240

1241+
// TODO: how on earth are we plumbing StatTree into here??
1242+
11991243
// The inbound flow ID must be calculated _after_ the
12001244
// header transformation. Remember, the "top"
12011245
// (outbound) of layer represents how the client sees
@@ -1308,6 +1352,8 @@ impl Layer {
13081352
});
13091353
}
13101354

1355+
// TODO: how on earth are we plumbing StatTree into here??
1356+
13111357
let desc = match action.gen_desc(pkt.flow(), pkt, ameta) {
13121358
Ok(aord) => match aord {
13131359
AllowOrDeny::Allow(desc) => desc,
@@ -1492,9 +1538,10 @@ impl Layer {
14921538
&mut self,
14931539
in_rules: Vec<Rule<Finalized>>,
14941540
out_rules: Vec<Rule<Finalized>>,
1541+
stats: &mut StatTree,
14951542
) {
14961543
self.ft.clear();
1497-
self.set_rules_core(in_rules, out_rules);
1544+
self.set_rules_core(in_rules, out_rules, stats);
14981545
}
14991546

15001547
/// Set all rules at once without clearing the flow table.
@@ -1505,18 +1552,20 @@ impl Layer {
15051552
&mut self,
15061553
in_rules: Vec<Rule<Finalized>>,
15071554
out_rules: Vec<Rule<Finalized>>,
1555+
stats: &mut StatTree,
15081556
) {
15091557
self.ft.mark_dirty();
1510-
self.set_rules_core(in_rules, out_rules);
1558+
self.set_rules_core(in_rules, out_rules, stats);
15111559
}
15121560

15131561
fn set_rules_core(
15141562
&mut self,
15151563
in_rules: Vec<Rule<Finalized>>,
15161564
out_rules: Vec<Rule<Finalized>>,
1565+
stats: &mut StatTree,
15171566
) {
1518-
self.rules_in.set_rules(in_rules);
1519-
self.rules_out.set_rules(out_rules);
1567+
self.rules_in.set_rules(in_rules, stats);
1568+
self.rules_out.set_rules(out_rules, stats);
15201569
self.stats.vals.set_rules_called += 1;
15211570
self.stats.vals.in_rules.set(self.rules_in.num_rules() as u64);
15221571
self.stats.vals.out_rules.set(self.rules_out.num_rules() as u64);
@@ -1532,6 +1581,7 @@ struct RuleTableEntry {
15321581
id: RuleId,
15331582
hits: u64,
15341583
rule: Rule<rule::Finalized>,
1584+
stat: Arc<TableStat>,
15351585
}
15361586

15371587
impl From<&RuleTableEntry> for RuleTableEntryDump {
@@ -1561,15 +1611,18 @@ pub enum RuleRemoveErr {
15611611
}
15621612

15631613
impl RuleTable {
1564-
fn add(&mut self, rule: Rule<rule::Finalized>) {
1614+
fn add(&mut self, rule: Rule<rule::Finalized>, stats: &mut StatTree) {
1615+
let stat = stats.root(rule.stat_id().copied());
15651616
match self.find_pos(&rule) {
15661617
RulePlace::End => {
1567-
let rte = RuleTableEntry { id: self.next_id, hits: 0, rule };
1618+
let rte =
1619+
RuleTableEntry { id: self.next_id, hits: 0, rule, stat };
15681620
self.rules.push(rte);
15691621
}
15701622

15711623
RulePlace::Insert(idx) => {
1572-
let rte = RuleTableEntry { id: self.next_id, hits: 0, rule };
1624+
let rte =
1625+
RuleTableEntry { id: self.next_id, hits: 0, rule, stat };
15731626
self.rules.insert(idx, rte);
15741627
}
15751628
}
@@ -1589,7 +1642,7 @@ impl RuleTable {
15891642
ifid: &InnerFlowId,
15901643
pmeta: &MblkPacketData,
15911644
ameta: &ActionMeta,
1592-
) -> Option<&Rule<rule::Finalized>> {
1645+
) -> Option<&RuleTableEntry> {
15931646
for rte in self.rules.iter_mut() {
15941647
if rte.rule.is_match(pmeta, ameta) {
15951648
rte.hits += 1;
@@ -1600,7 +1653,7 @@ impl RuleTable {
16001653
ifid,
16011654
&rte.rule,
16021655
);
1603-
return Some(&rte.rule);
1656+
return Some(rte);
16041657
}
16051658
}
16061659

@@ -1738,10 +1791,14 @@ impl RuleTable {
17381791
}
17391792
}
17401793

1741-
pub fn set_rules(&mut self, new_rules: Vec<Rule<rule::Finalized>>) {
1794+
pub fn set_rules(
1795+
&mut self,
1796+
new_rules: Vec<Rule<rule::Finalized>>,
1797+
stats: &mut StatTree,
1798+
) {
17421799
self.rules.clear();
17431800
for r in new_rules {
1744-
self.add(r);
1801+
self.add(r, stats);
17451802
}
17461803
}
17471804
}
@@ -1825,6 +1882,7 @@ mod test {
18251882
use crate::engine::predicate::Predicate;
18261883
use crate::engine::rule;
18271884

1885+
let mut stats = StatTree::default();
18281886
let mut rule_table = RuleTable::new("port", "test", Direction::Out);
18291887
let mut rule = Rule::new(
18301888
1,
@@ -1835,7 +1893,7 @@ mod test {
18351893
Ipv4AddrMatch::Prefix(cidr),
18361894
]));
18371895

1838-
rule_table.add(rule.finalize());
1896+
rule_table.add(rule.finalize(), &mut stats);
18391897

18401898
let mut test_pkt = MsgBlk::new_ethernet_pkt((
18411899
Ethernet { ethertype: Ethertype::IPV4, ..Default::default() },

0 commit comments

Comments
 (0)