1// Copyright 2024 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
45//! Declares types and functionality related to the state of raw IP sockets.
67use derivative::Derivative;
8use lock_order::lock::{OrderedLockAccess, OrderedLockRef};
9use netstack3_base::sync::RwLock;
10use netstack3_base::{IpExt, Marks, WeakDeviceIdentifier};
1112use crate::internal::raw::counters::RawIpSocketCounters;
13use crate::internal::raw::filter::RawIpSocketIcmpFilter;
14use crate::internal::raw::protocol::RawIpSocketProtocol;
15use crate::internal::raw::RawIpSocketsBindingsTypes;
16use crate::internal::socket::SocketHopLimits;
1718/// State for a raw IP socket that can be modified, and is lock protected.
19#[derive(Derivative)]
20#[derivative(Default(bound = ""))]
21pub struct RawIpSocketLockedState<I: IpExt, D: WeakDeviceIdentifier> {
22/// The socket's bound device. When set, the socket will only be able to
23 /// send/receive packets via this device.
24 ///
25 /// Held as a weak identifier, because binding a socket to a device should
26 /// not obstruct removal of the device.
27pub(crate) bound_device: Option<D>,
28/// The socket's ICMP filters. When set, all received ICMP packets will need
29 /// to pass the filter, in order to be delivered to the socket.
30pub(crate) icmp_filter: Option<RawIpSocketIcmpFilter<I>>,
31/// The socket's hop limits.
32pub(crate) hop_limits: SocketHopLimits<I>,
33/// Whether the socket should loop back sent multicast traffic.
34#[derivative(Default(value = "true"))]
35pub(crate) multicast_loop: bool,
36/// The sockets' marks.
37pub(crate) marks: Marks,
38/// Whether the system should generate/validate checksums for packets
39 /// sent/received by this socket.
40// TODO(https://fxbug.dev/343672830): Support enabling/disabling checksum
41 // support on IPv6 sockets. At the moment this is statically determined by
42 // the socket's protocol.
43pub(crate) system_checksums: bool,
44}
4546/// State held by a raw IP socket.
47pub struct RawIpSocketState<I: IpExt, D: WeakDeviceIdentifier, BT: RawIpSocketsBindingsTypes> {
48/// The bindings state associated with this socket.
49external_state: BT::RawIpSocketState<I>,
50/// The IANA Internet Protocol of this socket.
51 ///
52 /// This field is specified at creation time and never changes.
53protocol: RawIpSocketProtocol<I>,
54/// The locked socket state, accessible via the [`RawIpSocketStateContext`].
55locked_state: RwLock<RawIpSocketLockedState<I, D>>,
56/// The counters for this socket.
57counters: RawIpSocketCounters<I>,
58}
5960impl<I: IpExt, D: WeakDeviceIdentifier, BT: RawIpSocketsBindingsTypes> RawIpSocketState<I, D, BT> {
61pub(super) fn new(
62 protocol: RawIpSocketProtocol<I>,
63 external_state: BT::RawIpSocketState<I>,
64 ) -> RawIpSocketState<I, D, BT> {
65 RawIpSocketState {
66 external_state,
67 protocol,
68 locked_state: Default::default(),
69 counters: Default::default(),
70 }
71 }
72pub(super) fn protocol(&self) -> &RawIpSocketProtocol<I> {
73&self.protocol
74 }
75pub(super) fn external_state(&self) -> &BT::RawIpSocketState<I> {
76&self.external_state
77 }
78pub(super) fn into_external_state(self) -> BT::RawIpSocketState<I> {
79let RawIpSocketState { protocol: _, locked_state: _, counters: _, external_state } = self;
80 external_state
81 }
8283/// Get the counters for this socket.
84pub fn counters(&self) -> &RawIpSocketCounters<I> {
85&self.counters
86 }
8788/// Helper function to circumvent lock ordering, for tests.
89#[cfg(test)]
90pub(super) fn locked_state(&self) -> &RwLock<RawIpSocketLockedState<I, D>> {
91&self.locked_state
92 }
93}
9495impl<I: IpExt, D: WeakDeviceIdentifier, BT: RawIpSocketsBindingsTypes>
96 OrderedLockAccess<RawIpSocketLockedState<I, D>> for RawIpSocketState<I, D, BT>
97{
98type Lock = RwLock<RawIpSocketLockedState<I, D>>;
99100fn ordered_lock_access(&self) -> OrderedLockRef<'_, Self::Lock> {
101 OrderedLockRef::new(&self.locked_state)
102 }
103}