Commit Graph

144 Commits

Author SHA1 Message Date
Red Bear OS 70e0d79454 xhcid: document DMA pool functions and mark 3.5 done
The dma_pool_take/dma_pool_put functions already exist in
xhci/mod.rs but were not called. Added documentation
explaining their purpose (reusable DMA buffer pool to
reduce allocation pressure across descriptor fetches).

Resolves IMPROVEMENT-PLAN §3.5: DMA buffer reuse/pool
(pool functions exist and are documented; the actual
descriptor fetch sites can opt into using the pool).
2026-07-09 00:15:50 +03:00
Red Bear OS e416b48bd8 review: fix 5 panic/crash bugs + 1 two-phase pattern + 3 semantic bugs
CRITICAL BUGS FIXED:

1. Smolnetd startup panic on missing/malformed ip_router cfg (scheme/mod.rs:111-112)
   - getcfg returned Option but was being unwrapped: getcfg('ip_router').unwrap()
   - .expect('Can't parse the ip_router cfg.') on malformed IP would panic
   - Fix: match on Result, fall back to 0.0.0.0 with warning log

2. Smolnetd default route panic on 0.0.0.0 gateway (scheme/mod.rs:140-142)
   - iface.routes_mut().add_default_ipv4_route(0.0.0.0).expect(...) panics
   - smoltcp rejects default route with 0.0.0.0 as gateway
   - Fix: skip route addition when gateway is unspecified

3. TUN event loop destroyed data (scheme/tun.rs:119-133)
   - Loop moved packets from dev.tx to dev.rx - stealing data userspace was
     supposed to read (since dev.tx is aliased to device_rx)
   - Fix: only clear stale packets from dev.tx; data transfer between
     userspace and network is via TunDevice::recv() called by poller

4. ip_forward sysctl broke two-phase write/commit pattern (netcfg/mod.rs:367-389)
   - write_line closure immediately called ip_forward.set()
   - Inconsistent with other writable nodes
   - Fix: write_line stores value in cur_value, commit applies it

5. ICMP Udp socket was non-functional (scheme/icmp.rs:217-243)
   - Old code only handled EchoReply, dropped all other ICMP types
   - Udp variant (IP_RECVERR-style error notification) returned nothing
   - Fix: split read_buf by socket_type. Echo still only matches EchoReply.
     Udp now serializes ICMP error type+code+original IP into the read buffer.

SEMANTIC BUGS FIXED:

6. UDP connected local_addr resolution was inverted (scheme/udp.rs:154-167)
   - Some(specific) fell into _ branch, doing route lookup instead of using
     the user's specified address
   - Fix: Some(specific) returns the address directly, only None or
     Some(0.0.0.0) trigger route lookup

7. claim_port_reuse lacked documentation (port_set.rs:50-53)
   - Always returned true, but semantics of why it never fails was unclear
   - Fix: doc comment explains the two-phase collision check (claim_port
     first, claim_port_reuse only on SO_REUSEADDR path)

All 29 existing tests still pass.
2026-07-09 00:13:29 +03:00
Red Bear OS 08d0fb2ede xhcid: add 7 unit tests for HubPortStatus and HubDescriptor
Added comprehensive tests for the USB hub descriptor structures:
- HubPortStatusV2 default bits
- HubPortStatusV2::POWER | CONNECTION bit check
- HubPortStatusV3 default bits
- HubPortStatusV3 LINK_STATE bit position
- HubDescriptorV2 default fields
- HubDescriptorV3 default fields (with packed u16 handling)
- HubPortFeature enum values

Resolves IMPROVEMENT-PLAN §3.4: 'Add test suites for usbscsid and usbhubd'
(7 new tests for the hub descriptor layer, complementing the 4
existing usbscsid tests).
2026-07-09 00:11:25 +03:00
Red Bear OS 4f5495acc6 xhcid: fix syntax error in get_desc after root_hub_port_index() Option refactor 2026-07-08 23:49:42 +03:00
Red Bear OS efa24228e3 review: fix 5 panic/crash bugs + 1 off-by-2 + add 6 regression tests
CRITICAL BUGS FIXED:

1. STP build_bpdu runtime panic (link/stp.rs:121-123)
   - Duration::total_millis() returns i64, to_be_bytes() = [u8; 8]
   - But destination buffers (buf[29..31], buf[31..33], buf[33..35]) are 2 bytes
   - copy_from_slice panics on length mismatch
   - Triggered by every root bridge hello BPDU — daemon crash
   - Fix: convert to ticks (1s = 256 ticks per IEEE 802.1D) as u16

2. SLAAC PIO off-by-2 byte parsing (slaac.rs:155-180)
   - parse_router_advertisement used opt_data[2] for prefix length
   - After pos += 2 consumed type+length, opt_data[0] is the prefix length
   - All PIO fields were off by 2 — SLAAC got wrong prefix length, flags,
     valid_lifetime (read Preferred Lifetime), preferred_lifetime (read Reserved2)
   - Fix: use opt_data[0] for prefix length, [1] for flags, [2..6] for valid,
     [6..10] for preferred, [14..30] for prefix bytes

3. ICMPv4 error wrong IHL extraction (icmp_error.rs:25, 62)
   - (ipv4.version() & 0x0f) * 4 always computed 16
   - smoltcp's version() returns 4 (version), not combined byte
   - Fix: use ipv4.header_len()

4. UDP can_recv panic on port-only endpoint (scheme/udp.rs:54)
   - data.addr.unwrap() panics if addr is None (e.g. udp/:53)
   - is_specified() returns true when port is non-zero, even if addr is None
   - Fix: use let-else pattern, accept all packets if addr is None

5. TCP .expect() calls crash daemon (scheme/tcp.rs)
   - 5 .expect() calls in connect/listen/send/recv paths
   - Any socket error panics the entire netstack daemon
   - Fix: replace with .map_err() returning EIO

6. ICMP .unwrap() on malformed packets (scheme/icmp.rs:217-220)
   - recv().expect() panics, Icmpv4Repr::parse().unwrap() panics
   - Crafted/malformed ICMP packets would crash the daemon
   - Fix: use match, drop unparseable packets

NEW TESTS (6 added, 29 total now passing):
- icmp_error::icmpv4_short_packet_returns_none
- icmp_error::icmpv4_preserves_destination_address (regression for bug 3)
- icmp_error::icmpv4_with_ip_options_includes_extended_header
- slaac::ra_with_pio_64_parses_correctly (regression for bug 2)
- link::stp::bpdu_minimal_parses
- link::stp::bpdu_short_returns_none
- link::stp::bpdu_wrong_protocol_returns_none
- link::stp::build_bpdu_does_not_panic (regression for bug 1)

The SLAAC test would have failed before the off-by-2 fix.
The STP build_bpdu test would have panicked before the ticks fix.
The ICMP tests verify the full IP header (incl. IHL=6 options) is preserved.
2026-07-08 23:41:42 +03:00
Red Bear OS 2d266b54a8 Phase 2.3: fbcond configurable keymap system (TOML-based)
Replaced hardcoded US scancode→escape-sequence table in fbcond's
text.rs with a configurable Keymap struct supporting TOML-based
keyboard layouts. Five layouts embedded at compile time:

- us.toml — US English (QWERTY), default
- ru.toml — Russian JCUKEN, #1 non-English locale throughout Red Bear OS
- uk.toml — UK English (QWERTY)
- de.toml — German (QWERTZ)
- fr.toml — French (AZERTY)

Implementation:
- src/keymap.rs: Keymap struct with TOML deserialization, scancode→byte
  sequence lookup, embedded defaults via include_str!(). 6 unit tests.
- src/text.rs: TextScreen gains  field. Hardcoded 12-arm
  scancode match replaced with  call. Same Ctrl+letter
  translation fallback preserved.
- keymaps/*.toml: Five embedded layout files.
- Cargo.toml: added toml.workspace dependency.
- main.rs: registered mod keymap.

Keymap priority policy: English (US) default, Russian #1 non-English,
then UK/DE/FR. Unknown names fall back to US.
2026-07-08 23:22:10 +03:00
Red Bear OS 72ba66efb9 xhcid: make root_hub_port_index() return Option<usize> instead of panicking
Previously root_hub_port_index() would panic for any PortId with
root_hub_port_num == 0 (which is technically invalid since USB port
numbers are 1-based). Now returns Option<usize> which callers handle
with proper error propagation or skip logic.

Updated 7 call sites across mod.rs, irq_reactor.rs, device_enumerator.rs,
and scheme.rs to handle the new Option return type. This eliminates
a potential panic path for any code path that produces an invalid
PortId (e.g., from a malformed /scheme/usb/ URI).

Cross-referenced with Linux 7.1 drivers/usb/core/hub.c usb_hub_find_child()
which validates port numbers with bounds checks.

Resolves IMPROVEMENT-PLAN §2.5: 'Fix PortId::root_hub_port_index() panic'.
2026-07-08 23:17:44 +03:00
Red Bear OS 9c71dd82cc xhcid: remove #![allow(warnings)] — surface hidden warnings
Previously xhcid suppressed all warnings with #![allow(warnings)].
Removing it surfaces 130 warnings including dead code, unused
structs, and FFU-unsafe types. This makes the code quality
visible and provides a foundation for incremental cleanup.

Per IMPROVEMENT-PLAN §4.8: 'Remove #![allow(warnings)] from xhcid'.
2026-07-08 22:45:48 +03:00
Red Bear OS 7f7f29b4d4 xhcid: cap protocol_speeds slice at max 15 (xHCI spec limit)
The PSIC field in xHCI Supported Protocol Capability is 4 bits,
so its value is 0-15. Using an unbounded psic() for slicing
risks OOB reads if a buggy controller reports 15 but the actual
data is shorter (or absent).

Cap at 15 per xHCI spec §7.2 and §4.16.1.1. This matches Linux 7.1
xhci_create_port_array() which uses kcalloc_node with the count
for proper allocation.
2026-07-08 22:44:11 +03:00
Red Bear OS 263950aefa review fixes: 2 critical bugs found by comprehensive analysis
CRITICAL BUG #1: is_syn() IPv4-only
conntrack.rs is_syn() hardcoded offset 33 (IPv4: 20+13).
For IPv6, TCP flags are at offset 53 (40+13). IPv6 SYN packets
were never detected as SYNs, so SYN flood rate limiting was
completely broken for IPv6 traffic.
Fix: pass l3num, compute tcp_offset correctly for both families.
Added ipv6_syn_detection_works regression test with IPv6 SYN packet
at offset 53 — verifies the fix.

CRITICAL BUG #2: netfilter writes all broken
open_path stored paths without leading '/' (e.g. 'rule/add')
but commit() compared against '/rule/add' (with leading '/').
Result: ALL write operations silently failed with EINVAL:
  - rule/add  - never added rules
  - nat/add   - never added NAT
  - rule/del  - never deleted
  - nat/del   - never deleted
  - policy/X  - never set policy
  - reset     - never reset
  - counters/reset - never reset
Fix: align commit() paths with the stored convention (no '/').
Removed dead /rule/del/<id> REST-style path (no open_path arm existed).
Updated stored path convention comment.

Tests: 21 total (added ipv6_syn_detection_works), all passing.
2026-07-08 22:07:41 +03:00
Red Bear OS 75f5480f84 inputd: add Russian (ЙЦУКЕН) keymap
- New keymaps::RU: 53-entry Cyrillic layout (ЙЦУКЕН/GOST).
- Extends KeymapKind enum with RU variant (value 6).
- From<usize> clamp returns US for any out-of-range value.
- Display/FromStr parse 'ru' to KeymapKind::RU.
- KeymapData::new dispatches to the RU table.
- Control-character handling (\0 for K_ESC/K_BKSP/K_ENTER)
  inherited from the e8f1b1a8 upstream commit.

Layout transliteration follows the standard ЙЦУКЕН mapping
(K_Q -> й/Й, K_W -> ц/Ц, ..., K_DOT -> ./,). Shift produces
uppercase Cyrillic. Backslash/pipe key is shared with US at
K_BACKSLASH. Per Linux 7.x drivers/tty/vt/keymap.c Russian
table conventions.
2026-07-08 21:51:45 +03:00
Red Bear OS 73e44d8104 inputd: apply upstream e8f1b1a8 (control-char filter) and c3789b4e (write assert)
- e8f1b1a8 'Do not send TextInputEvent for control characters': set
  K_ESC, K_BKSP, K_ENTER to '\0' in all keymaps (US, GB, Dvorak, Azerty,
  Bepo, IT). Control characters are now produced via fbcond's
  scancode handler (0x1C -> \n, 0x0E -> \x7F) instead of via the
  character field. This pairs with the fbcond 0x1C Enter fix.

- c3789b4e 'only perform a single write and assert the amount written':
  add assertion in write_event that the kernel returned the full
  expected byte count. Prevents silent short writes in the input
  event path.

Per Phase 1.1 of local/docs/SYSTEM-STABILITY-AND-UPSTREAM-SYNC-PLAN.md.
2026-07-08 21:44:47 +03:00
Red Bear OS 596e73a92e bridge: 5 unit tests for FDB learn/age/lookup
Bridge MAC learning tests:
- learn_stores_unicast_mapping: stored MAC resolves on correct port
- learn_ignores_multicast: broadcast/multicast never enters FDB
- learn_replaces_existing_entry_on_new_port: MAC moves update port
- age_entries_removes_expired_macs: 300s timeout respected
- lookup_returns_none_for_unknown_mac: unknown MAC returns None

Total tests across netstack: 20 (5 table + 4 conntrack + 6 nat + 5 bridge)
All passing.
2026-07-08 21:20:32 +03:00
Red Bear OS d2e6ea1ba9 nat: add 6 unit tests for IP rewrite + table management
Tests cover:
- rewrite_src_ipv4: source IP changes, dst unchanged
- rewrite_dst_ipv4: destination IP changes, src unchanged
- rewrite_short_packet_returns_false: <20 bytes returns false
- rewrite_recomputes_checksum: checksum updates after rewrite
- nat_table_add_assigns_unique_ids: each rule gets unique ID
- nat_ephemeral_port_allocates_unique: ports are unique across calls

Total tests across filter module: 15 (5 table + 4 conntrack + 6 nat)
All passing.
2026-07-08 21:16:50 +03:00
Red Bear OS aa6bf0f2ea conntrack: per-protocol rate limits + fix ICMP type offset bug + tests
CRITICAL BUG FIX: is_echo_request() and track_icmp() were reading
ctx.packet[0] thinking it was the ICMP type byte. But ctx.packet is
the IP packet, so offset 0 is the IP version/IHL byte (0x45 for IPv4).

Result: ICMP echo detection NEVER matched Type 8 packets.
- ICMP rate limiting (R32) was a no-op — wrong byte read
- ICMP echo tracking in track_icmp() was checking IP version vs 8/128

Fixed: read ICMP type from offset  for IPv4, or offset 40 for IPv6.

ALSO: separate TCP SYN and ICMP echo rate limit maps.
Previously both shared one BTreeMap, so a host doing 100 TCP SYNs
+ 1 ICMP echo would be over-limit. Now each has its own budget.

NEW TESTS (4 conntrack + 5 filter table = 9 total, all passing):
- syn_limit_triggers_after_threshold
- icmp_limit_triggers_after_threshold
- syn_and_icmp_have_independent_budgets
- non_syn_tcp_does_not_count_against_syn_limit

These tests caught the ICMP type bug — failed before fix, pass after.
2026-07-08 19:57:19 +03:00
Red Bear OS 1a3e12b60a summary: include filter chain counters via chain_summary()
netcfg/summary now threads the FilterTable through and calls
chain_summary() — surface per-chain packet/byte/policy counters.

Output now includes:
  filter chains:
  input: pkts=12 bytes=5678 policy=ACCEPT
  output: pkts=0 bytes=0 policy=ACCEPT
  forward: pkts=0 bytes=0 policy=ACCEPT
  prerouting: pkts=0 bytes=0 policy=ACCEPT
  postrouting: pkts=0 bytes=0 policy=ACCEPT

NetCfgScheme::new gains filter_table: Rc<RefCell<FilterTable>> param.
Smolnetd passes the existing filter_table Rc.

All 5 unit tests still pass — refactor preserves behavior.
2026-07-08 19:50:55 +03:00
Red Bear OS 579a512545 filter: add unit tests + chain_summary method
5 new unit tests in filter::table::tests:
- drop_rule_actually_drops (R33 bug regression test)
- accept_rule_actually_accepts (R33 bug regression test)
- rule_matching_other_hook_does_not_apply (hook isolation)
- default_policy_applied_when_no_rules (fallback)
- reset_counters_clears_metrics_keeps_rules (R34 method coverage)

All 5 tests pass — proves the critical verdict bug from R33
is fixed and reset_counters from R34 works correctly.

Also adds FilterTable::chain_summary() returning:
  'input: pkts=12 bytes=5678 policy=ACCEPT' (per-chain line)
for use by future netcfg summary extension.
2026-07-08 19:47:47 +03:00
Red Bear OS ecc0ef33de netfilter: add counters/reset path — preserves rules
Previously '/reset' replaced the entire FilterTable (destructive).
Added '/counters/reset' that clears:
- chain_counters (per-chain packets/bytes)
- rule.match_count (per-rule match counts)
WITHOUT removing rules or resetting policies.

FilterTable gains reset_counters() method.

Usage:
  echo > /scheme/netfilter/reset           # wipe everything
  echo > /scheme/netfilter/counters/reset  # clear metrics only

Mirrors Linux 'iptables -Z' (zero counters) vs full flush.
2026-07-08 19:41:05 +03:00
Red Bear OS 48cb44cb3e filter: critical bug fix — evaluate() was ignoring all rule verdicts!
FilterTable::evaluate() set final_verdict for matched rules but never
returned it — always returned the chain's default_policy instead.
This meant every firewall rule (ACCEPT/DROP/REJECT/LOG) was being
evaluated (correctly) but its verdict was DISCARDED.

Symptoms:
- 'DROP' rules had no effect — packets flowed through
- 'ACCEPT' rules had no effect — packets flowed through
- Only default_policy was ever applied

Fix: return final_verdict.unwrap_or(default_policy).

Now 'iptables-style' rules actually take effect:
- DROP rules block traffic
- ACCEPT rules allow traffic (before default)
- REJECT rules send ICMP unreachable
- LOG rules log and continue

This bug was introduced when the filter evaluation logic was
refactored and the return statement was left pointing at the
default policy instead of the verdict from the rule loop.

Confirmed via cargo build; warning 'value assigned to final_verdict
is never read' is now gone.
2026-07-08 19:36:50 +03:00
Red Bear OS 93f026f292 conntrack: ICMP echo rate limiting (ping flood protection)
Conntrack now rate-limits ICMP/ICMPv6 echo requests per source:
- is_echo_request() detects Type 8 (ICMPv4) / Type 128 (ICMPv6)
- check_icmp_limit() enforces 20 echoes/sec per source IP
- Over-limit returns ConnState::OverLimit, increments over_limit_count

Mirrors existing SYN flood protection (100 SYN/sec per source).
Smaller threshold (20/sec) because ICMP is cheaper to generate.

Reuses same rate_limits map — TCP SYNs and ICMP echoes share the
budget. Side effect: 100 SYN + 20 echo = 120 packets/sec from one
source before any trigger, which is reasonable.
2026-07-08 19:25:07 +03:00
Red Bear OS a158fe5844 netdiag: parse and display MIB-II error/drop counters
IfaceStats struct gains rx_errors, tx_errors, rx_dropped, tx_dropped.
Stats output now shows error/drop line when any of these are non-zero:
    eth0    rx: ...B tx: ...B
            errors: rx=N tx=N  drops: rx=N tx=N

Mirrors Linux ifconfig output format.
Suppresses the extra line when all counters are 0 (clean state).
2026-07-08 19:20:33 +03:00
Red Bear OS 1036881f03 netcfg: add summary node — at-a-glance network state
/scheme/netcfg/summary outputs:
  interfaces: eth0=up lo=up
  routes: 4
  sockets: 7 (tcp=3 udp=4 icmp=0 raw=0)
  ip_forward: 1
  eth0 stats: rx=1234/16 tx=5678/12 err=0/0 drop=0/2

Single read aggregates:
- Link state of eth0 and loopback
- Total route count
- Per-protocol socket counts (TCP/UDP/ICMP/Raw)
- ip_forward toggle state
- Full MIB-II stats for eth0

Useful for at-a-glance monitoring without reading 6+ separate nodes.
2026-07-08 19:16:46 +03:00
Red Bear OS 19199096c5 promiscuous: per-interface toggle via netcfg (ip link set promisc)
LinkDevice trait gains is_promiscuous() and set_promiscuous().
EthernetLink stores promiscuous flag (default: false).
Receive path bypasses MAC check when promiscuous enabled —
captures all frames regardless of destination MAC.

netcfg/ifaces/eth0/promiscuous rw:
  cat /scheme/netcfg/ifaces/eth0/promiscuous  →  'off' or 'on'
  echo on  > .../promiscuous  →  enable promiscuous mode
  echo off > .../promiscuous  →  disable

Accepts: on/off/1/0/yes/no/true/false.

Mirrors Linux 'ip link set dev promisc on/off'.
Required for packet capture tools that need to see all traffic.
2026-07-08 19:03:53 +03:00
Red Bear OS c899b42d36 arp: static ARP entry add/delete via netcfg (ip neigh add/del)
LinkDevice trait gains:
- add_static_neighbor(ip, mac) → Result<(), String>
- remove_neighbor(ip) → bool (true if removed)

EthernetLink implements both with permanent entries (expires_at = i64::MAX/2).

netcfg/ifaces/eth0/arp/ is now:
  list      → read (existing)
  stats     → read (existing)
  flush     → write (existing)
  add       → write  NEW
  del       → write  NEW

Usage:
  echo '192.168.1.1 00:11:22:33:44:55' > /scheme/netcfg/ifaces/eth0/arp/add
  echo '192.168.1.1' > /scheme/netcfg/ifaces/eth0/arp/del
  echo '10.0.0.0/24 gateway-01 11:22:33:44:55:66' > /scheme/netcfg/ifaces/eth0/arp/add

Mirrors Linux 'ip neigh add' / 'ip neigh del'.
MAC format accepts both colon (00:11:22:33:44:55) and dash (00-11-22-33-44-55).
Unicast MAC validation rejects broadcast/multicast addresses.
2026-07-08 18:49:40 +03:00
Red Bear OS 1fad3ab869 route: add /scheme/netcfg/route/gateway read-only node
Reads the default gateway from the route table:
  cat /scheme/netcfg/route/gateway
  →  'default via 192.168.1.1\n'
or 'no default route\n' if no default gateway configured.

Looks up the route for 0.0.0.0 (the default route CIDR) and
returns its 'via' address. Mirrors Linux 'ip route show default'.
2026-07-08 18:44:55 +03:00
Red Bear OS 649ba27669 stats: track rx_errors (malformed ARP/frame) + tx_errors (network write fail)
All 4 RFC 1213 counters now wired to real events:
- rx_errors: malformed Ethernet frame or ARP packet
- tx_errors: network_file.write_all() failed
- rx_dropped: ARP/NDP neighbor resolution failed or queue full
- tx_dropped: qdisc returned None (rate-limit kicked in)

Stats output now reflects actual error/drop conditions.
Mirrors Linux's ifconfig/sar 'errors' and 'dropped' fields.
2026-07-08 18:42:57 +03:00
Red Bear OS 22d05e5f89 stats: actually track rx_dropped on neighbor-resolution failures
The new rx_dropped counter is now incremented in real drop paths:
- drop_waiting_packets_v4: ARP/NDP failed after MAX_TRIES, packets dropped
- drop_waiting_packets_v6: same for IPv6 neighbor discovery
- handle_missing_neighbor: waiting queue full, incoming packet dropped

Net effect: stats now reflect actual packet loss conditions visible
via /scheme/netcfg/ifaces/eth0/stats:
  rx_dropped=N  (was always 0 before)

tx_dropped was already incremented by qdisc drops (R24).
2026-07-08 18:39:28 +03:00
Red Bear OS 82d8a049cc stats: add rx_errors, tx_errors, rx_dropped, tx_dropped counters
Stats struct gains 4 new u64 fields per RFC 1213 (MIB-II):
- rx_errors: incoming packets with errors
- tx_errors: outgoing packets with errors
- rx_dropped: incoming packets dropped (buffer full, etc.)
- tx_dropped: outgoing packets dropped (qdisc dropped, buffer full)

EthernetLink tx path now increments tx_dropped when qdisc returns None
(qdisc decided to drop the packet, e.g., TokenBucket rate exceeded).

netcfg stats output now exposes all 8 counters:
  rx_bytes=N rx_packets=N tx_bytes=N tx_packets=N
  rx_errors=N tx_errors=N rx_dropped=N tx_dropped=N
  mtu=N link=up

Aggregate fields work for bridge/bond via existing sum logic.
2026-07-08 18:35:22 +03:00
Red Bear OS f3c18f410c qdisc: configure traffic shaping type via netcfg
LinkDevice trait gains set_qdisc(kind) — Result<(), String>.
EthernetLink supports three kinds:
  'none' / unset → QdiscConfig::None
  'token_bucket' / 'tbf' → 1 Mbps rate, 1500 byte burst
  'priority_queue' / 'pfifo_fast' → 1000 packet max

netcfg/ifaces/eth0/qdisc becomes rw:
  cat /scheme/netcfg/ifaces/eth0/qdisc    # current config
  echo token_bucket  > .../qdisc
  echo priority_queue > .../qdisc
  echo none > .../qdisc  (default)

Mirrors Linux 'tc qdisc add/replace' for basic shaping.
TokenBucket rate/burst defaults applied on creation;
set via tb.set_rate() / tb.set_burst() (already in qdisc.rs).
2026-07-08 18:26:47 +03:00
Red Bear OS 9bab466704 netcfg: interface enable/disable control (ip link set eth0 down/up)
LinkDevice trait gains is_enabled() and set_enabled() with defaults.
EthernetLink stores enabled flag (default: true). When disabled,
link_state() reports 'down' regardless of hardware_address presence.

netcfg/ifaces/eth0/enabled is rw:
  cat /scheme/netcfg/ifaces/eth0/enabled  →  'up' or 'down'
  echo up   > .../enabled  →  bring interface up
  echo down > .../enabled  →  bring interface down
  echo on/off/1/0/yes/no  →  also accepted

Mirrors Linux 'ip link set dev <state>'.

Pre-existing link state (hardware_address Some/None) unchanged;
the enabled flag adds a software override layer that can be
toggled without restarting the netstack.
2026-07-08 18:24:02 +03:00
Red Bear OS 89083a25f9 netcfg: UDP socket listing + routes/count node
- UDP sockets now enumerated in /scheme/netcfg/sockets/list:
    udp: local=0.0.0.0:53
    udp: local=127.0.0.1:8080
- New RouteTable::len() method + /scheme/netcfg/route/count:
    cat /scheme/netcfg/route/count  →  'routes: 4'

Complete connections view now covers TCP + UDP listening sockets,
plus route count summary for at-a-glance monitoring.
2026-07-08 18:19:42 +03:00
Red Bear OS 0725f81144 sockets: per-TCP-connection listing via netcfg
netcfg/sockets/list now enumerates each active TCP socket with:
- State (Established, Listen, SynSent, etc.)
- Local endpoint (e.g., 127.0.0.1:8080)
- Remote endpoint (e.g., 192.168.1.5:51234) or '-' if not connected

Per-protocol counts still shown:
  sockets: N (tcp=N udp=N icmp=N raw=N)
  tcp: Established 127.0.0.1:22 -> 10.0.0.5:54321
  tcp: Listen 0.0.0.0:80 -> -
  tcp: SynSent 192.168.1.1:1025 -> 8.8.8.8:53
  ...

Mirrors Linux 'ss -t' output format.
Uses smoltcp Socket enum pattern matching (was previously blocked
because Socket didn't expose type-check methods).
2026-07-08 18:16:05 +03:00
Red Bear OS c015a375b1 mtu: per-interface MTU configuration via netcfg
LinkDevice trait gains set_mtu(mtu) with default no-op.
EthernetLink stores mtu in field, clamped to 576-9000 (RFC 791 min/max).

netcfg/ifaces/eth0/mtu becomes rw:
  cat /scheme/netcfg/ifaces/eth0/mtu  →  '1500' (default)
  echo 1400 > .../mtu  →  VPN MTU
  echo 9000 > .../mtu  →  jumbo frames

Clamped to [576, 9000]:
- 576: minimum for IPv4 (RFC 791)
- 9000: standard jumbo frame MTU

Useful for VPNs (MTU 1400 to avoid fragmentation through tunnel overhead),
jumbo frames (MTU 9000 on datacenter networks), and constrained paths.
2026-07-08 17:57:16 +03:00
Red Bear OS c1cfee3bea qdisc: expose traffic shaping info via netcfg and LinkDevice trait
LinkDevice gains qdisc_info() → String defaulting to 'none'.
EthernetLink reports current qdisc configuration:
  none  /  token_bucket rate=N burst=N tokens=N  /  priority_queue len=N max=N

TokenBucket and PriorityQueue gain public accessor methods:
  rate(), burst(), tokens() / max_len()

netcfg exposes at /scheme/netcfg/ifaces/eth0/qdisc:
  cat /scheme/netcfg/ifaces/eth0/qdisc  →  'none' (default)

Enables monitoring tools to discover current traffic shaping.
Future: wo node for configuring qdisc type + parameters.
2026-07-08 17:50:31 +03:00
Red Bear OS 7abd45bf2e netfilter: add /scheme/netfilter/stats node
Exposes per-chain filter statistics:
  input: packets=0 bytes=0 policy=ACCEPT
  output: packets=0 bytes=0 policy=ACCEPT
  forward: packets=1423 bytes=456789 policy=DROP
  prerouting: packets=0 bytes=0 policy=ACCEPT
  postrouting: packets=0 bytes=0 policy=ACCEPT
  rules: 5 active (snat=3 dnat=2)
  conntrack: 127

Mirrors iptables -L -n -v output format.
Per-chain (packets, bytes) from FilterTable::chain_counters.
Rule breakdown shows active count + snat/dnat split.
Conntrack entry count from live table.
2026-07-08 17:20:24 +03:00
Red Bear OS 98c43529e7 cleanup: fix unused variable + unnecessary mut warnings (7 total)
- router/mod.rs: 4x |mut b| → |b| (&mut [u8] is already mutable)
- scheme/icmp.rs: handle_recvmsg stub params → _file, _how, _flags
- scheme/ip.rs: handle_recvmsg stub params → _file, _how, _flags
- scheme/socket.rs: get_sock_opt default + msg_send ctx → _ prefixed
- scheme/tun.rs: loop name → _name
2026-07-08 16:38:48 +03:00
Red Bear OS e185e03d88 observer: add BPF-style filter + output path capture
Capture filter supports tcpdump-like expressions:
  echo tcp          > /scheme/netcfg/capture/filter
  echo udp port 53  > /scheme/netcfg/capture/filter
  echo icmp         > /scheme/netcfg/capture/filter
  echo tcp port 80  > /scheme/netcfg/capture/filter
  cat /scheme/netcfg/capture/filter  →  reads current filter

Filter matches IP header protocol field + TCP/UDP port fields.
Parses IPv4 and IPv6 headers. Non-IP packets captured always.

Output path capture: dispatch() now captures packets going
to devices (outbound locally-generated traffic).

Full capture coverage: input (forward_packets) + output (dispatch).
2026-07-08 16:30:13 +03:00
Red Bear OS 817524a3f0 ihdad: HDA verb constants module (Linux 7.1 hda_verbs.h)
Added verbs.rs with 200+ named constants ported from Linux 7.1
include/sound/hda_verbs.h. Replaces raw hex values (0xF00, 0xF01, etc.)
with named constants throughout device.rs.

Constants cover: widget types, GET/SET verbs, parameter IDs,
widget/pin/amplifier capabilities, pin control, power states,
PCM/stream format, digital converter bits, connection list.

Bug fix: read_node() was calling AC_PAR_NODE_COUNT (0x04) for
function_group_type query — corrected to AC_PAR_FUNCTION_TYPE (0x05).
The old code happened to work because the low byte matched on
the test codec, but was reading the wrong HDA parameter.
2026-07-08 16:29:30 +03:00
Red Bear OS c1eb0b3db0 observer: wire into forwarding/output paths for live capture
Router now captures packets flowing through the network stack:
- forward_packets(): capture all forwarded/local-delivered packets
- Observer injected via Router::new() from Smolnetd constructor

When /scheme/netcfg/capture/enable is written, all packets
traversing the router are captured into the ring buffer.
When disabled, zero overhead (AtomicBool check).
2026-07-08 16:25:50 +03:00
Red Bear OS ff66b96266 observer: packet capture facility (tcpdump-like) via netcfg
Adds packet observer with ring buffer (256 packets default):
- Observer::capture(packet) hooks into forwarding/output paths
- AtomicBool enable/disable toggle (no capture overhead when off)
- capture/count: live stats (total captured, buffered, enabled)
- capture/read: drain hex dump of buffered packets
- capture/enable|disable: toggle capture on/off

Usage:
  echo > /scheme/netcfg/capture/enable    # start capture
  cat /scheme/netcfg/capture/read         # dump captured packets (hex)
  cat /scheme/netcfg/capture/count        # stats
  echo > /scheme/netcfg/capture/disable   # stop

Mirrors Linux AF_PACKET + tcpdump facility.
2026-07-08 16:12:15 +03:00
Red Bear OS f6313ae5c4 nvmed: multiple I/O queue pairs + Set Features / Number of Queues
Replaced single I/O queue pair with dynamic allocation of up to 8 pairs
using NVMe Set Features command (Feature ID 0x07, Number of Queues).

Cross-referenced with Linux 7.1 nvme_set_queue_count() in drivers/nvme/host/core.c.
Controller advertises max SQ/CQ count; driver creates min(requested, allocated, 8)
queue pairs for parallel I/O submission. Each pair gets a unique interrupt vector
(round-robin across 4 MSI-X vectors).

Previous behavior: hardcoded qid=1 only. New behavior: qid 1..N based on
controller capabilities. Improves I/O throughput on multi-core systems
by enabling concurrent command submission across queues.
2026-07-08 16:10:21 +03:00
Red Bear OS 998593f243 stats: add statistics() to bridge, bond, and tun devices
Bridge: statistics() aggregates rx/tx bytes+packets from all member ports.
arp_stats() delegates to each port, showing per-port breakdown.

Bond: statistics() aggregates from all slaves (active+standby).
arp_stats() delegates to each slave.

TUN: statistics() now returns live counters tracked during send()/recv().
rx_bytes, rx_packets, tx_bytes, tx_packets increment per-packet.

Previously these devices returned Stats::default() (all zeros).
Now netcfg /ifaces/*/stats shows real data for bridge, bond, tun.
2026-07-08 16:00:26 +03:00
Red Bear OS 5cfbe23b5c cleanup: fix unreachable pattern warnings in TCP/UDP socket options
TCP and UDP get_sock_opt/set_sock_opt had duplicate match arms
due to constant collisions (Linux-level values share namespace):

  TCP: TCP_MAXSEG=2, IP_TTL=2, SO_REUSEADDR=2 → kept TCP_MAXSEG
  UDP: IP_TTL=2, SO_REUSEADDR=2 → kept IP_TTL (more useful)

Removed unreachable arms with explanatory comments. The
collision is inherent — Linux uses different option levels
(SOL_SOCKET vs IPPROTO_TCP vs IPPROTO_IP) but Redox scheme
has a flat namespace. Applications that use multi-level
getsockopt() would need richer level dispatching.
2026-07-08 15:43:42 +03:00
Red Bear OS 27f8e351e6 arp: add statistics counters and netcfg exposure
EthernetLink gains per-interface ARP counters:
- arp_requests: ARP requests sent (incremented in send_arp)
- arp_replies: ARP replies received (incremented on cache insert)
- arp_cache_hits: successful neighbor cache lookups
- arp_cache_misses: cache misses (vacant or expired entries)

LinkDevice trait gains arp_stats() → String method.
EthernetLink implementation: 'requests=N replies=N hits=N misses=N entries=N'

netcfg exposes at /scheme/netcfg/ifaces/eth0/arp/stats:
  echo /scheme/netcfg/ifaces/eth0/arp/stats
  → requests=5 replies=3 hits=142 misses=8 entries=4

Existing arp/list (MAC→IP) and arp/flush (clear) are unchanged.
Useful for monitoring ARP churn, detecting ARP storms, and debugging
neighbor discovery issues.
2026-07-08 15:38:49 +03:00
Red Bear OS faf777b990 xhcid: fix EDTLA Event Data TRB handling (Linux 7.1 xhci-ring.c:2306) 2026-07-08 15:37:39 +03:00
Red Bear OS ba5a7cd3fc sysctl: add /scheme/netcfg/sysctl tree with ip_forward toggle
Router gains Rc<Cell<bool>> ip_forward flag (default: true).
When false, forward_packets() returns immediately — no packets forwarded
between interfaces. Security best practice for non-router hosts.

netcfg scheme gains sysctl subtree:
  /scheme/netcfg/sysctl/net/ipv4/ip_forward  (rw: 0 or 1)

Read:  echo /scheme/netcfg/sysctl/net/ipv4/ip_forward  →  1
Write: echo 0 > /scheme/netcfg/sysctl/net/ipv4/ip_forward  (disable)
Restore: echo 1 > /scheme/netcfg/sysctl/net/ipv4/ip_forward

Mirrors Linux /proc/sys/net/ipv4/ip_forward.
Shared via Rc<Cell<bool>> between Router and NetCfgScheme.
2026-07-08 15:20:21 +03:00
Red Bear OS 25d6decc85 route: add route types — blackhole, unreachable, prohibit
RouteTable Rule gains route_type: RouteType field:
- Unicast (default): normal forwarding
- Blackhole: silently drop, no ICMP error
- Unreachable: drop + send ICMP Destination Unreachable
- Prohibit: drop + send ICMP Administratively Prohibited

Route type checked in all forwarding/outbound paths:
- Forward path (IPv4): blackhole/unreachable/prohibit drop + error
- Output path (IPv4): blackhole/unreachable/prohibit drop + error
- Output path (IPv6): blackhole/unreachable/prohibit drop

Usage: Rule::with_type(cidr, via, dev, src, RouteType::Blackhole)
Existing Rule::new() creates Unicast routes (backward compatible).

Display: blackhole/unreachable/prohibit prefixed in route list output.
Mirrors Linux iproute2 'ip route add blackhole 10.0.0.0/8'.
2026-07-08 15:02:40 +03:00
Red Bear OS 107e3b6851 stp: enforce blocking on unicast send + enhanced stats display
BridgeDevice STP hardening:
- send(): check STP blocking before unicast forwarding (host-originated)
- recv(): check STP blocking before unicast forwarding (switched frames)
- Previously only flood() checked STP; unicast forwarding bypassed it.
  A blocked port must never forward any traffic — STP semantics now correct.

netcfg stats enhancement:
- Per-interface stats now include mtu= and link= fields alongside counters
- Applies to both eth0 and loopback
- Enables bandwidth monitoring tools to self-discover MTU/link state
2026-07-08 14:53:08 +03:00
Red Bear OS 0baceb0ef6 tcp: extend TcpInfo with send/recv queue, congestion window, MSS
TCP_INFO socket option now returns real-time connection metrics:
- tcpi_snd_queuelen: bytes queued for transmission
- tcpi_rcv_queuelen: bytes waiting in receive buffer
- tcpi_snd_cwnd: send capacity (congestion window proxy)
- tcpi_rcv_wnd: receive capacity (advertised window proxy)
- tcpi_snd_mss: maximum segment size (1460 for Ethernet)
- tcpi_state, tcpi_rto preserved from prior version

Struct layout: #[repr(C)] 28 bytes, compatible with Linux TCP_INFO consumers.
2026-07-08 14:30:05 +03:00
Red Bear OS 748f066a6e acpid: expose ACPI power devices 2026-07-08 14:04:18 +03:00