Revert "netstack: add proptest cases to filter/table + filter/conntrack"

This reverts commit b9e2ec31d5.
This commit is contained in:
Red Bear OS
2026-07-26 20:46:57 +09:00
parent 5d1ed3178d
commit 44cd0f8b51
2 changed files with 1 additions and 305 deletions
-113
View File
@@ -856,116 +856,3 @@ fn make_v6_ctx<'a>(protocol: u8, packet: &'a [u8]) -> PacketContext<'a> {
"TimeWait state should keep the connection alive for 120s");
}
}
#[cfg(test)]
mod proptest_tests {
extern crate proptest;
use super::*;
use proptest::prelude::*;
use crate::filter::Hook;
use smoltcp::time::Instant;
use core::hash::{Hash, Hasher};
fn ipv4_addr() -> impl Strategy<Value = IpAddress> {
(any::<u8>(), any::<u8>(), any::<u8>(), any::<u8>())
.prop_map(|(a, b, c, d)| IpAddress::v4(a, b, c, d))
}
fn ipv6_addr() -> impl Strategy<Value = IpAddress> {
(any::<[u8; 16]>())
.prop_map(|octets| IpAddress::from(smoltcp::wire::Ipv6Address::from_bytes(&octets)))
}
fn any_ip_addr() -> impl Strategy<Value = IpAddress> {
prop_oneof![ipv4_addr(), ipv6_addr()]
}
fn conn_key_strat() -> impl Strategy<Value = ConnKey> {
(
prop_oneof![Just(4u8), Just(6u8)],
prop_oneof![Just(6u8), Just(17u8), Just(1u8), Just(58u8)],
any_ip_addr(),
any_ip_addr(),
any::<u16>(),
any::<u16>(),
)
.prop_map(|(l3num, l4proto, src_addr, dst_addr, src_port, dst_port)| ConnKey {
l3num,
l4proto,
src_addr,
dst_addr,
src_port,
dst_port,
})
}
proptest! {
#[test]
fn prop_conntrack_insert_lookup_no_panic(key in conn_key_strat()) {
let reply_key = key.reply();
let double_reply = reply_key.reply();
assert_eq!(key, double_reply,
"reply(reply(key)) must equal the original key");
use std::collections::hash_map::DefaultHasher;
let mut h1 = DefaultHasher::new();
let mut h2 = DefaultHasher::new();
key.hash(&mut h1);
key.hash(&mut h2);
assert_eq!(h1.finish(), h2.finish(),
"repeated hash must be deterministic");
use std::collections::BTreeMap;
let mut map: BTreeMap<ConnKey, u32> = BTreeMap::new();
map.insert(key.clone(), 1);
assert!(map.contains_key(&key), "inserted key must be found");
assert_eq!(map.get(&key), Some(&1), "value must be retrievable");
if key.src_addr != key.dst_addr || key.src_port != key.dst_port {
assert_ne!(key, reply_key,
"reply key must differ from original when asymmetric");
}
}
#[test]
fn prop_conntrack_bulk_insert_no_panic(
keys in proptest::collection::vec(conn_key_strat(), 0..200)
) {
for key in &keys {
let _reply = key.reply();
for other in &keys {
if key == other {
assert_eq!(key.reply(), other.reply(),
"equal keys must have equal replies");
}
}
}
}
#[test]
fn prop_rate_limiters_independent(
syn_count in 0u32..50u32,
icmp_count in 0u32..10u32,
) {
let mut ct = ConntrackTable::new();
let now = Instant::from_secs(0);
for _i in 0..syn_count {
let _ = ct.check_syn_limit(IpAddress::v4(10, 0, 0, 1), now);
}
for _i in 0..icmp_count {
let limited = ct.check_icmp_limit(IpAddress::v4(10, 0, 0, 2), now);
assert!(!limited || icmp_count > 20,
"ICMP should not be limited at count {} (limit is 20/sec)", icmp_count);
}
}
#[test]
fn prop_clean_expired_no_panic() {
let mut ct = ConntrackTable::new();
let now = Instant::from_secs(0);
ct.clean_expired(now);
assert_eq!(ct.len(), 0, "empty table cleanup should not panic");
}
}
}
+1 -192
View File
@@ -527,195 +527,4 @@ mod tests {
assert_eq!(t.rules.len(), 1,
"reset_counters must preserve rules");
}
}
#[cfg(test)]
mod proptest_tests {
extern crate proptest;
use super::*;
use proptest::prelude::*;
use alloc::rc::Rc;
use smoltcp::time::Instant;
fn ipv4_addr_strat() -> impl Strategy<Value = IpAddress> {
(any::<u8>(), any::<u8>(), any::<u8>(), any::<u8>())
.prop_map(|(a, b, c, d)| IpAddress::v4(a, b, c, d))
}
fn hook_strat() -> impl Strategy<Value = Hook> {
prop_oneof![
Just(Hook::PreRouting),
Just(Hook::InputLocal),
Just(Hook::Forward),
Just(Hook::OutputLocal),
Just(Hook::PostRouting),
]
}
fn verdict_strat() -> impl Strategy<Value = Verdict> {
prop_oneof![
Just(Verdict::Accept),
Just(Verdict::Drop),
Just(Verdict::Log),
Just(Verdict::Reject),
]
}
fn filter_rule_strat() -> impl Strategy<Value = FilterRule> {
(
any::<u32>(),
hook_strat(),
proptest::option::of(ipv4_addr_strat()),
any::<u8>(),
proptest::option::of(ipv4_addr_strat()),
any::<u8>(),
proptest::option::of(any::<u8>().prop_map(Protocol)),
proptest::option::of(any::<u16>()),
proptest::option::of(any::<u16>()),
verdict_strat(),
)
.prop_map(
|(id, hook, src_addr, src_prefix_len, dst_addr, dst_prefix_len,
protocol, src_port, dst_port, verdict)| {
FilterRule {
id,
hook,
src_addr,
src_prefix_len: src_prefix_len.min(32),
dst_addr,
dst_prefix_len: dst_prefix_len.min(32),
protocol,
src_port,
dst_port,
in_dev: None,
out_dev: None,
state_match: None,
verdict,
match_count: 0,
}
},
)
}
fn packet_ctx_strat() -> impl Strategy<Value = PacketContext<'static>> {
(hook_strat(), ipv4_addr_strat(), ipv4_addr_strat(), any::<u8>(),
proptest::option::of(any::<u16>()),
proptest::option::of(any::<u16>()))
.prop_map(|(hook, src_addr, dst_addr, protocol, src_port, dst_port)| {
PacketContext {
hook,
in_dev: None,
out_dev: None,
src_addr,
dst_addr,
protocol,
src_port,
dst_port,
packet: &[],
}
})
}
proptest! {
#[test]
fn prop_filter_table_evaluate_no_panic(
rules in proptest::collection::vec(filter_rule_strat(), 0..20),
ctx in packet_ctx_strat(),
) {
let mut table = FilterTable::new();
let now = Instant::from_millis(0);
for mut rule in rules {
table.add(rule);
}
let verdict = table.evaluate(&ctx, now);
let _ = verdict.as_u32();
let _ = verdict.name();
assert!(Verdict::from_u32(verdict.as_u32()).is_some(),
"evaluate must return a valid verdict");
let _summary = table.chain_summary();
let _format = table.format();
}
#[test]
fn prop_filter_table_add_remove_roundtrip(
rules in proptest::collection::vec(filter_rule_strat(), 0..10),
) {
let mut table = FilterTable::new();
let mut ids = Vec::new();
for mut rule in rules {
let id = table.add(rule);
ids.push(id);
}
for &id in &ids {
assert!(table.remove(id),
"rule {} must be removable just after being added", id);
}
for &id in &ids {
assert!(!table.remove(id),
"removing already-removed rule {} must return false", id);
}
}
#[test]
fn prop_parse_rule_no_panic(input in "\PC*") {
let result = parse_rule(&input);
match result {
Ok(rule) => {
let _ = rule.id;
let _ = rule.verdict.name();
assert!(Hook::from_u32(rule.hook.as_u32()).is_some(),
"parsed hook must be valid");
}
Err(e) => {
let _ = e.to_string();
}
}
}
#[test]
fn prop_reset_counters_preserves_rules(
rules in proptest::collection::vec(filter_rule_strat(), 1..10),
) {
let mut table = FilterTable::new();
let count = rules.len();
for mut rule in rules {
table.add(rule);
}
table.set_default_policy(Hook::InputLocal, Verdict::Drop);
let now = Instant::from_millis(0);
let ctx = PacketContext {
hook: Hook::InputLocal,
in_dev: None, out_dev: None,
src_addr: IpAddress::v4(10, 0, 0, 1),
dst_addr: IpAddress::v4(10, 0, 0, 2),
protocol: 6,
src_port: Some(1234), dst_port: Some(80),
packet: &[],
};
let _ = table.evaluate(&ctx, now);
table.reset_counters();
assert_eq!(table.rules.len(), count,
"reset_counters must preserve all rules");
assert_eq!(
table.default_policy.get(&Hook::InputLocal).copied(),
Some(Verdict::Drop),
"reset_counters must preserve default policy"
);
for (_hook, (pkts, bytes)) in &table.chain_counters {
assert_eq!(*pkts, 0, "pkts must be zero after reset");
assert_eq!(*bytes, 0, "bytes must be zero after reset");
}
for rule in &table.rules {
assert_eq!(rule.match_count, 0,
"rule {} match_count must be zero after reset", rule.id);
}
}
}
}
}