1use net_types::ip::{Ipv4, Ipv6};
6use netstack3_base::{ContextPair, Inspector};
7
8use crate::{
9 FilterBindingsTypes, FilterContext, FilterIpContext, Routines, ValidRoutines, ValidationError,
10};
11
12pub struct FilterApi<C>(C);
14
15impl<C> FilterApi<C> {
16 pub fn new(ctx: C) -> Self {
18 Self(ctx)
19 }
20}
21
22impl<C> FilterApi<C>
23where
24 C: ContextPair,
25 C::CoreContext: FilterContext<C::BindingsContext>
26 + FilterIpContext<Ipv4, C::BindingsContext>
27 + FilterIpContext<Ipv6, C::BindingsContext>,
28 C::BindingsContext: FilterBindingsTypes,
29{
30 fn core_ctx(&mut self) -> &mut C::CoreContext {
31 let Self(pair) = self;
32 pair.core_ctx()
33 }
34
35 pub fn set_filter_state<RuleInfo: Clone>(
45 &mut self,
46 v4: Routines<Ipv4, <C::BindingsContext as FilterBindingsTypes>::DeviceClass, RuleInfo>,
47 v6: Routines<Ipv6, <C::BindingsContext as FilterBindingsTypes>::DeviceClass, RuleInfo>,
48 ) -> Result<(), ValidationError<RuleInfo>> {
49 let (v4_installed, v4_uninstalled) = ValidRoutines::new(v4)?;
50 let (v6_installed, v6_uninstalled) = ValidRoutines::new(v6)?;
51
52 self.core_ctx().with_all_filter_state_mut(|v4, v6| {
53 if v4_installed.get().nat.contains_rules() {
54 v4.nat_installed.set();
55 }
56 if v6_installed.get().nat.contains_rules() {
57 v6.nat_installed.set();
58 }
59
60 v4.installed_routines = v4_installed;
61 v4.uninstalled_routines = v4_uninstalled;
62 v6.installed_routines = v6_installed;
63 v6.uninstalled_routines = v6_uninstalled;
64 });
65
66 Ok(())
67 }
68
69 pub fn inspect_state<N: Inspector>(&mut self, inspector: &mut N) {
71 inspector.record_child("IPv4", |inspector| {
72 FilterIpContext::<Ipv4, _>::with_filter_state(self.core_ctx(), |state| {
73 inspector.delegate_inspectable(state);
74 });
75 });
76 inspector.record_child("IPv6", |inspector| {
77 FilterIpContext::<Ipv6, _>::with_filter_state(self.core_ctx(), |state| {
78 inspector.delegate_inspectable(state);
79 });
80 });
81 }
82}