1// Copyright 2025 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.
45use netstack3_base::Mark;
67/// An action that can be applied to a mark.
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum MarkAction {
10/// This action sets the mark specified by the `mark` and `clearing_mask`.
11 ///
12 /// If the current mark is [`None`], it will just set it to `mark`.
13SetMark {
14/// This value will be combined with the result of the masking using a
15 /// bitwise OR to get the final mark.
16mark: u32,
17/// The bits specified by this mask will be cleared out from the
18 /// existing mark.
19clearing_mask: u32,
20 },
21}
2223impl MarkAction {
24/// Applies the change to the given [`Mark`].
25pub fn apply(self, mark: &mut Mark) {
26let Mark(cur) = mark;
27match self {
28 MarkAction::SetMark { clearing_mask, mark } => {
29*cur = Some(match cur {
30Some(v) => (*v & !clearing_mask) | mark,
31None => mark,
32 });
33 }
34 }
35 }
36}
3738#[cfg(test)]
39mod tests {
40use super::*;
41use test_case::test_case;
4243#[test_case(Mark(None), MarkAction::SetMark { mark: 1, clearing_mask: 0 } => Mark(Some(1))
44 ; "set new mark")]
45 #[test_case(Mark(Some(1)), MarkAction::SetMark { mark: 2, clearing_mask: 1 } => Mark(Some(2))
46 ; "clear with mask")]
47 #[test_case(Mark(Some(1)), MarkAction::SetMark { mark: 2, clearing_mask: 0 } => Mark(Some(3))
48 ; "or mark")]
49fn apply_mark_action(mut mark: Mark, action: MarkAction) -> Mark {
50 action.apply(&mut mark);
51 mark
52 }
53}