Preprint
Article

This version is not peer-reviewed.

A Decision-Diagram Framework for Conflict Detection in Multi-Layer Cilium Network Policies

Submitted:

07 July 2026

Posted:

08 July 2026

You are already at the latest version

Abstract

Cilium is among the most widely deployed Container Network Interfaces (CNIs), serving as the default CNI in Google Kubernetes Engine. It extends standard Kubernetes NetworkPolicy (KNP) with two additional types—CiliumNetworkPolicy (CNP) and CiliumClusterwideNetworkPolicy (CCNP)—each with distinct semantics. When all three coexist in a cluster, the resulting composition is difficult to reason about formally, leading to misconfiguration and security incidents. Existing verification tools, KANO and VeriKube, address subsets of the problem but share two critical limitations: neither provides a formal denotational semantics that precisely characterizes the three-layer composition, nor a canonical representation enabling policy-equivalence checking with completeness guarantees. We close this gap with three contributions. First, we develop the first formal denotational semantics for Cilium’s three-layer composed policy—KNP (additive), CNP (deny-wins), CCNP (cluster-override)—and prove that the composite function is Hyper-Rectangular Piecewise-Constant (HRPC-like). Second, we construct a canonical Reduced Ordered Interval Decision Diagram (ROIDD) for the composite policy space and prove a canonicity theorem, enabling policy-equivalence checking as structural isomorphism in O(|ROIDD|) time. Third, we develop certified conflict-detection algorithms for shadow, redundancy, and cross-layer conflict anomalies across all three layers with formal proofs of soundness and completeness. Experimental evaluation on synthetic policies confirms zero mismatches between ROIDD evaluation and ground-truth brute-force, ROIDD compression ratios of 5–15× over the unshared decision tree, and low-microsecond (0.56–1.52 µs) per-packet lookup latency regardless of policy size. A native C++ implementation, evaluated on the same policy dataset, reconstructs the identical decision-diagram structure and classifies each packet in under 45 ns—about 30× faster than the Python reference—confirming that sub-microsecond classification is inherent to the algorithm rather than an artifact of the implementation language.

Keywords: 
;  ;  ;  ;  ;  ;  ;  

1. Introduction

Cilium is among the most widely deployed Container Network Interfaces (CNIs), serving as the default CNI in Google Kubernetes Engine and available as an option in Amazon EKS and Azure Kubernetes Service. It extends standard Kubernetes NetworkPolicy (KNP) with two additional policy types—CiliumNetworkPolicy (CNP) and CiliumClusterwideNetworkPolicy (CCNP)—each enforced by Cilium’s eBPF-based data plane. When all three policy types coexist in a production cluster, the resulting composition is difficult to reason about without formal support. A CNP deny rule, a KNP allow rule, and a CCNP cluster-deny rule can interact in non-obvious ways, producing shadow rules, unreachable traffic regions, and cross-layer conflicts that are invisible to the administrator [1,2].
Existing verification tools address subsets of this problem. KANO [3] models Kubernetes NetworkPolicy verification using a bipartite reachability bit-matrix but handles only KNP’s additive semantics and provides no formal proof of detection completeness. VeriKube [4] extends KANO to Cilium policy semantics using a novel graph structure, achieving significant performance improvements, but provides no formal denotational model, no canonical representation, and no proofs. Scenario-based approaches such as the VDM-SL formalization of Kulik and Boudjadar [5] lack conflict-detection algorithms entirely. This paper closes the gap by providing three certified contributions.
C1 — Three-layer formal semantics. We develop the first denotational semantics that precisely characterizes Cilium’s three-layer policy composition and prove that the composite function is Hyper-Rectangular Piecewise-Constant (HRPC-like)—a key structural property exploited by our decision-diagram construction.
C2 — Canonical ROIDD. We construct a Reduced Ordered Interval Decision Diagram (ROIDD) for the composite policy space and prove a canonicity theorem (Myhill–Nerode argument), enabling policy-equivalence checking as structural isomorphism in O(|ROIDD|) time.
C3 — Certified conflict detection. We develop algorithms for shadow (Algorithm 2), redundancy (Algorithm 3), and cross-layer conflict and unreachable-region detection (Algorithm 4), each with formal proofs of soundness and completeness absent in all prior work.
Scope of this work: L3/L4 packet-level policies (IP prefix, port, protocol, endpoint label identity). L7 proxy policies and multi-cluster (ClusterMesh) are left to future work.
The rest of the paper is organized as follows. Section 2 reviews related work. Section 3 formalizes the three-layer composite semantics. Section 4 constructs the ROIDD and proves canonicity. Section 5 presents conflict-detection algorithms with proofs. Section 6 reports experimental results. Section 7 discusses implications and future directions. Section 8 concludes.

3. Formal Semantics of Three-Layer Cilium Policy

3.1. Packet Space and Action Set

Definition 1 (Packet Space).
Let F = {sip, dip, sport, dport, proto, slabel, dlabel} be the set of L3/L4 fields. Each field Fi has a finite ordered domain D(Fi). The packet space is U = ∏ D(Fi). A packet p ∈ U is a tuple (p1, …, p7).
Remark. Each D(Fi) is a finite set of consecutive integers under its natural order. For sip/dip this order is numeric address order: a CIDR block c/m is encoded as the closed integer interval [base(c), base(c) + 2^(32−m) − 1] before truncation to the compressed field domain of Section 6.1; for slabel/dlabel it is the order induced by σ (Definition 2). An interval Iij ⊆ D(Fj) (Definition 8) is always such a closed range [lo, hi] of consecutive integers—never a union of disjoint ranges—consistent with Definition 9 (O4).
Definition 2 (Action Set).
The action set is A = {allow, deny, cluster-deny} with priority ordering cluster-deny ≻ deny ≻ allow. A policy function is any f: U → A.
The label fields slabel and dlabel represent Kubernetes label-sets of source and destination endpoints, respectively. Each label-set is mapped to a finite integer index via a fixed injection σ: Labels → ℕ, making D(slabel) and D(dlabel) finite ordered domains. This is the key departure from classical firewall models that operate only on IP/port tuples.
Remark. Layer functions ⟦r⟧_KNP, ⟦Ψ⟧_CNP, ⟦Γ⟧_CCNP take values in A⊥ := A ∪ {⊥}, where ⊥ (“not applicable”) means that layer expresses no opinion for p. The composite ⟦Π⟧ (Definition 7) is total: it maps every p ∈ U to a value in A, never ⊥, so ROIDD terminals (O1) are labelled only with A.

3.2. Single-Layer Semantics

Definition 3 (KNP Rule Semantics).
For a KNP rule r and packet p: ⟦r⟧_KNP(p) = allow if p matches all fields of r; ⊥ otherwise.
Definition 4 (KNP Policy Semantics).
For a KNP policy Φ = (r1, …, rn) and packet p:
⟦Φ⟧_KNP(p) = allow if ∃ r_i ∈Φ with ⟦r_i⟧_KNP(p) = allow,
⟦Φ⟧_KNP(p) = deny if endpoint isolated and no rule allows p,
⟦Φ⟧_KNP(p) = allow if endpoint not isolated (no rule selects it).
Remark. Formally, let isolatedΦ(p) ∈ {true, false} indicate whether some KNP rule’s endpoint selector applies to p’s relevant endpoint—a predicate over the label fields alone, itself interval-based (Definition 8) and hence HRPC-like. The three cases of ⟦Φ⟧_KNP above are mutually exclusive (an allow verdict requires a matching rule, which forces isolatedΦ(p) = true) and exhaustive over isolatedΦ(p) ∈ {true, false}, so ⟦Φ⟧_KNP is total (never ⊥), matching Definition 2’s codomain A.
Remark. KNP is allow-only: the allow-lists of all matching rules are unioned. Default-deny applies only when the endpoint is isolated [8].
Definition 5 (CNP Policy Semantics).
For a CNP policy Ψ and packet p:
⟦Ψ⟧_CNP(p) = deny if ∃ r ∈Ψ with p in deny-list of r,
⟦Ψ⟧_CNP(p) = allow if no deny matches and ∃ r ∈Ψ with p in allow-list of r,
⟦Ψ⟧_CNP(p) = ⊥ otherwise (not applicable to this endpoint).
Source [6]: “Deny policies take precedence over allow policies, regardless of whether they are a CiliumNetworkPolicy, a CiliumClusterwideNetworkPolicy, or even a Kubernetes NetworkPolicy.”
Definition 6 (CCNP Policy Semantics).
For a CCNP policy Γ and packet p:
⟦Γ⟧_CCNP(p) = cluster-deny if ∃ r ∈Γ with p in deny-list of r,
⟦Γ⟧_CCNP(p) = allow if no deny matches and ∃ r ∈Γ with p in allow-list of r,
⟦Γ⟧_CCNP(p) = ⊥ otherwise.
Remark. ⟦Ψ⟧_CNP(p) = ⊥ precisely when no CNP rule (allow or deny) matches p, i.e., this layer contributes no verdict for p—distinct from ⟦Ψ⟧_CNP(p) = deny, which requires an explicit matching deny rule. The same convention applies to ⟦Γ⟧_CCNP. Definition 7 below resolves every combination in A⊥ × A⊥ × A⊥ via default-deny, so ⊥ never propagates into ⟦Π⟧.

3.3. Composition Semantics

Definition 7 (Cilium Composite Semantics).
Let Π = (KNP, CNP, CCNP) be a Cilium policy configuration. The composite function ⟦Π⟧: U → A is:
⟦Π⟧(p) = cluster-deny if ⟦Γ⟧_CCNP(p) = cluster-deny;
⟦Π⟧(p) = deny if ⟦Γ⟧_CCNP(p) ≠ cluster-deny and ⟦Ψ⟧_CNP(p) = deny;
⟦Π⟧(p) = allow if ⟦Γ⟧_CCNP(p) = allow, or ⟦Ψ⟧_CNP(p) = allow, or ⟦Φ⟧_KNP(p) = allow;
⟦Π⟧(p) = deny otherwise (default-deny: endpoint isolated, no allow matches).
Priority intuition: (1) CCNP deny overrides everything; (2) CNP deny overrides any allow; (3) any allow from any layer passes the packet if no deny applies; (4) absence of any allow with isolation triggers default-deny.
Remark. Formally, define compose: A⊥ × A⊥ × A⊥ → A by compose(aK, aC, aCC) = cluster-deny if aCC = cluster-deny; deny if aCC ≠ cluster-deny and aC = deny; allow if aCC = allow or aC = allow or aK = allow; deny otherwise—where aK = ⟦Φ⟧_KNP(p) ∈ {allow, deny} (Definition 4, never ⊥), aC = ⟦Ψ⟧_CNP(p) ∈ A⊥, and aCC = ⟦Γ⟧_CCNP(p) ∈ A⊥. These four cases are mutually exclusive by construction (each successive case applies only when all earlier conditions fail) and exhaustive over A⊥³, so ⟦Π⟧(p) := compose(⟦Φ⟧_KNP(p), ⟦Ψ⟧_CNP(p), ⟦Γ⟧_CCNP(p)) is well-defined and total on U.

3.4. Composite Policy Is HRPC-like

Definition 8 (HRPC-like Function).
A function f: U → A is hyper-rectangular piecewise-constant (HRPC-like) if there exists a finite partition of U into hyper-rectangles H1, …, Hm (each Hi = ∏ Iij for intervals Iij⊆ D(Fj)) such that f is constant on each Hi.
Lemma 3 (Isolation and no-match predicates are HRPC-like).
For any layer L ∈ {KNP, CNP, CCNP}, the predicate isolatedΦ: U → {true, false} (Definition 4) and the predicate “no rule of L matches p” (used in Definitions 5–6) are HRPC-like functions of p.
Proof. Each predicate is a finite Boolean combination—a disjunction, for “some rule of L selects/matches p,” and its negation for “no rule matches”—of individual rule predicates; by Definition 1’s remark, each rule predicate is itself a conjunction of single closed-interval tests and hence HRPC-like, constant on each cell of the grid induced by that rule’s own breakpoints. A finite Boolean combination of HRPC-like functions is HRPC-like: the common refinement of the underlying partitions (pairwise intersection of their hyper-rectangles) is again a finite partition into hyper-rectangles, and every Boolean combination is constant on each cell of that refinement. Consequently isolatedΦ’s (and the analogous no-match predicates’) breakpoints already lie among the breakpoints Bj contributed by L’s own rules (Algorithm 1, Phase 1), so no grid refinement beyond G is needed for Theorem 1 to cover the case splits of Definitions 4–6 directly. □
Theorem 1 (Composite Policy is HRPC-like).
For any Cilium policy configuration Π = (KNP, CNP, CCNP) consisting of finitely many rules, the composite function ⟦Π⟧: U → A is HRPC-like.
Proof sketch. Step 1: every rule predicate is a conjunction of interval conditions F1∈ I1∧ ⋯ ∧ F7∈ I7. Let Bj be the set of breakpoints of all rules along field Fj across all layers. The product grid G = ∏j Gj partitioned at Bj is a finite partition of U into hyper-rectangles. Within any cell c ∈ G, every rule either covers all of c or none, making ⟦Φ⟧_KNP, ⟦Ψ⟧_CNP, and ⟦Γ⟧_CCNP constant on c (by Lemma 3, this includes the isolation/no-match conditions used in Definitions 4–6). ✓ Step 2: the composition ⟦Π⟧(p) = compose(…) is a deterministic function of three constant values, hence also constant on c. Since G is a finite partition of U into hyper-rectangles, ⟦Π⟧ is HRPC-like. □
Remark. Each rule’s predicate is a conjunction of single closed-interval tests (Definition 1’s remark), so its match set restricted to one field with the others fixed is itself a single interval; hence the breakpoint set Bj (Algorithm 1, Phase 1) partitions D(Fj) into atoms on which every rule of every layer, and so ⟦Φ⟧_KNP, ⟦Ψ⟧_CNP, ⟦Γ⟧_CCNP, is individually constant. This alone does not guarantee that atoms sharing one output value are contiguous; Algorithm 1 (Phase 2) tests atoms in order and merges only adjacent atoms with equal output, producing single-interval edges (O4) by construction, at the possible cost of extra nodes when the same value recurs non-adjacently. Theorem 3 and Lemma 2 below show this run-length discipline is itself canonical.
Corollary 1.
Every Cilium policy configuration has a finite ROIDD under a fixed field order π, representing ⟦Π⟧. Canonicity of this ROIDD—and the resulting equivalence-oracle property that ⟦Π⟧ = ⟦Πʹ⟧ if and only if ROIDD(Π, π) ≅ ROIDD(Πʹ, π)—is established below in Theorem 3 and Corollary 2.

4. ROIDD for Cilium Policy

Theorem 1 guarantees every Cilium composite policy is HRPC-like. We construct a canonical representation as a Reduced Ordered Interval Decision Diagram (ROIDD), the three-valued, interval-domain analogue of Bryant’s ROBDD [18] and the direct extension of FDD [9].

4.1. Ordered Interval Decision Diagrams

Definition 9 (OIDD).
An Ordered Interval Decision Diagram (OIDD) under field order π is a rooted DAG satisfying:
(O1) Terminals: labelled with elements of A = {allow, deny, cluster-deny}.
(O2) Non-terminals: each labelled with a field F(v) ∈ F.
(O3) Ordered: field labels strictly increase along π on every root-to-terminal path.
(O4) Edge labels: each edge e carries I(e) ⊆ D(F(v)), a single (maximal) interval.
(O5) Consistency: I(e) ∩ I(eʹ) = ∅ for any two distinct edges from the same node.
(O6) Completeness: ∪ I(e) = D(F(v)) over all outgoing edges of any node v.
Definition 10 (OIDD Semantics).
For an OIDD f and packet p ∈ U, ⟦f⟧(p) is the label of the unique terminal reached from the root by following, at each non-terminal v, the unique edge e with p[F(v)] ∈ I(e).
Reduction rules: (R1) Share isomorphic nodes—two nodes are isomorphic if both are terminals with identical labels, or both are non-terminals with the same field label and a bijection between outgoing edges with identical interval labels pointing to the same child. Remove vʹ and redirect all edges to v. Apply bottom-up to a fixed point. (R2) Eliminate redundant tests—if all outgoing edges of non-terminal v point to the same node w, remove v and redirect incoming edges to w.
Lemma 1 (Reduction preserves semantics).
Applying R1 or R2 to an OIDD f yields fʹ with ⟦fʹ⟧ = ⟦f⟧.
Proof. R1: isomorphic nodes return identical decisions for all inputs. R2: if all children of v are w, the test on F(v) is irrelevant. Both operations are semantics-preserving. □
Definition 11 (ROIDD).
A Reduced Ordered Interval Decision Diagram (ROIDD) under field order π is an OIDD where R1 and R2 have been applied bottom-up to a fixed point.

4.2. Construction Algorithm

Algorithm 1 (ROIDD Construction).
Input: Π = (KNP, CNP, CCNP), field order π. Output: ROIDD(Π, π).
Phase 1 — Collect breakpoints: For each field Fj, collect all interval endpoints from all rules across all layers, forming the breakpoint set Bj.
Phase 2 — Build per-layer OIDDs: For each layer L, build OIDDL by Shannon decomposition along π. At depth k, partition D(Fπ(k)) at Bπ(k) breakpoints; create one child per maximal constant interval; recurse. At depth 7 (all fields tested), label the node as a terminal with ⟦L⟧(p) for any representative p.
Phase 3 — Compose: Merge OIDD_KNP, OIDD_CNP, OIDD_CCNP using the apply operation from Definition 7. At each leaf triple (aK, aC, aCC), output compose(…) ∈ A.
Phase 4 — Reduce: Apply R1 and R2 exhaustively bottom-up using hash-cons to identify and merge isomorphic nodes.

Complexity: O(|G|·|F|) for Phase 2, where |G| = ∏j (|Bj|+1) ≤ (2·|rules|+1)^7 in the worst case (exponential in |F| = 7, though bounded in practice by the actual breakpoint counts). Phase 3 (apply) is O(|OIDD_KNP|·|OIDD_CNP|·|OIDD_CCNP|) via a synchronized traversal of the three per-layer diagrams. Phase 4 is O(|ROIDD| log |ROIDD|) using hash-cons for node dedup.
Theorem 2 (Correctness of Algorithm 1).
Let f = ROIDD(Π, π). Then ⟦f⟧(p) = ⟦Π⟧(p) for all p ∈ U.
Proof sketch. We show, by downward induction on depth k = 7,…,0, the invariant: the subdiagram reached after fixing Fπ(1),…,Fπ(k) computes p ↦ ⟦Π⟧(p) restricted to that fixing. Base case k = 7: breakpoints (Phase 1) ensure each layer’s terminal is constant, hence correct, on its atom, and Phase 3 applies compose (Definition 7) pointwise at each leaf triple, so the merged terminal equals ⟦Π⟧ at every representative packet of the cell. Inductive step: if the invariant holds at depth k+1 for every child, then at depth k the node’s edge-to-child map (Phase 2) reproduces exactly the case split of Definition 7 restricted to Fπ(k), so the invariant holds at k. Phase 4 preserves the invariant by Lemma 1, since R1/R2 do not alter ⟦·⟧. At k = 0 (the root) the invariant gives ⟦ROIDD(Π, π)⟧ = ⟦Π⟧ on all of U. Composing: ⟦ROIDD(Π, π)⟧ = ⟦Π⟧.□

4.3. Canonicity and Equivalence Oracle

Lemma 2 (Run-length canonicity).
Fix π and depth k. Let g: D(Fπ(k)) → S be constant on each atom of the finite ordered partition from Algorithm 1’s breakpoints (S any finite set of residual functions of the remaining fields). Define a π-run of g as a maximal set of consecutive atoms on which g is constant. The π-runs of g partition D(Fπ(k)) into intervals, and this partition is unique.
Proof. Declare two adjacent atoms equivalent iff g agrees on both; take the transitive closure of this adjacency relation. Because D(Fπ(k)) is totally ordered, each resulting class is a set of consecutive atoms, i.e., an interval [lo, hi]: if a class contained two atoms with a non-equivalent atom between them, that middle atom would break the adjacency chain, contradicting transitive closure over ADJACENT equal atoms. Maximality is immediate from the definition of “run.” Uniqueness follows because the total order on D(Fπ(k)) admits exactly one partition into maximal runs of a fixed function value: any coarser interval grouping would merge two atoms with differing g-values, and any finer grouping would split a maximal run, both contradicting maximality. □
Remark. Restricting edges to single intervals (O4) means two non-adjacent atoms with equal residual function are not merged into one edge: each contributes its own edge, though R1 still shares their (identical) child subtree as one node. This does not weaken canonicity—Theorem 3’s uniqueness is stated, and holds, relative to Definition 9 exactly as given—but it can increase edge count relative to a hypothetical union-interval encoding. The increase is bounded: at any node, at most |Bj| ≤ 2·|rules| atoms exist for that field, so that node has at most |Bj| edges regardless of adjacency, preserving the polynomial size bound of Algorithm 1’s complexity statement. We adopt single intervals because it matches Algorithm 1’s actual construction (Phase 2 merges only adjacent atoms) and keeps the intersection test I(e) ∩ H(r)[F(v)] used by Algorithm 2 simple interval arithmetic rather than the more expensive union arithmetic a merged encoding would require.
Theorem 3 (Canonicity).
Under fixed field order π, every HRPC-like function f: U → A has a unique ROIDD up to isomorphism. Equivalently: ROIDD(Π, π) ≅ ROIDD(Πʹ, π) if and only if ⟦Π⟧ = ⟦Πʹ⟧.
Proof (Myhill–Nerode induction). We prove, by downward induction on depth k = 7,…,0, that the subdiagram representing f restricted to any fixing of Fπ(1),…,Fπ(k) is unique up to isomorphism.
Base case (k = 7). Every field is fixed, so f itself determines a single value in A; the terminal node is unique by definition of a terminal (O1).
Inductive step (depth k+1 → depth k). Assume every subdiagram at depth k+1 is unique up to isomorphism; by hash-consing (R1) each is assigned a unique node identity. Define g: D(Fπ(k)) → {node identities at depth k+1} by g(v) = the identity of the depth-(k+1) subdiagram obtained by fixing Fπ(k) = v; g is well-defined by the inductive hypothesis. Since f is HRPC-like, g is constant on each atom of the breakpoint partition of D(Fπ(k)) determined by Bπ(k) (Algorithm 1, Phase 1; Lemma 3 covers the isolation/no-match conditions). By Lemma 2, the π-runs of g—the maximal intervals on which g is constant—form a unique partition of D(Fπ(k)). Definition 9 (O4) requires exactly one edge per π-run, so the node at depth k has a uniquely determined edge set: the run-length partition (unique, Lemma 2) paired with each run’s child identity g(run) (unique, inductive hypothesis). If all edges share one child, R2 collapses the node to that child; otherwise the node’s hash-cons key—(field, edge list, child list)—is itself uniquely determined by the above, so R1 assigns it a unique identity. This establishes the inductive step.
Conclusion. At k = 0 the induction yields a unique root identity, i.e., a unique ROIDD up to isomorphism for the fixed order π. Finiteness—so the induction runs in finitely many steps and each level has finitely many atoms—follows because Π has finitely many rules: each Bj has at most 2·|rules| breakpoints (Lemma 3 shows the isolation/no-match predicates add none), giving finitely many atoms and hence finitely many π-runs (Lemma 2) at every depth. Since ROIDD(Π,π) and ROIDD(Πʹ,π) are each built by this same unique construction from ⟦Π⟧ and ⟦Πʹ⟧ respectively, they are isomorphic exactly when ⟦Π⟧ = ⟦Πʹ⟧, which is the stated equivalence. □
Corollary 2 (Equivalence oracle).
⟦Π⟧ = ⟦Πʹ⟧ if and only if ROIDD(Π, π) ≅ ROIDD(Πʹ, π) (for the same fixed field order π; comparing diagrams built under different orders requires re-ordering first). Isomorphism checking runs in O(|ROIDD|) using hash-cons: Phase 4 assigns each node a canonical key from its (field, edge-list, child-id) tuple during the bottom-up pass, so two ROIDDs are isomorphic iff their root keys coincide in the shared hash table—an O(1) lookup after the O(|ROIDD|) hash-cons pass, assuming O(1) amortized hash-table operations and that edge labels are already canonicalized to single intervals (O4) via Algorithm 1’s adjacent-atom merge, so that isomorphic edge lists compare equal as keys without further normalization.
The ROIDD is canonical for a fixed π. Finding the optimal field order is NP-hard in general (as for ROBDD variable ordering), but practical heuristics include placing high-fan-out fields and label fields early. Field-order sensitivity does not affect correctness or the equivalence-oracle property; it affects only ROIDD size.

5. Conflict Detection Algorithms

We now define the four anomaly types relevant to Cilium’s multi-layer setting and provide certified detection algorithms. Note that classical firewall anomalies (shadow, redundancy, correlation) are defined for single-layer first-match models [11]; our definitions must account for the deny-wins and cluster-override semantics of Cilium.
Remark. Throughout this section, Π, ROIDD(Π, π), and π are as guaranteed by Theorems 2–3: ROIDD(Π, π) is semantically faithful (⟦ROIDD(Π,π)⟧ = ⟦Π⟧) with deterministic, single-valued terminals (O1). H(r) denotes the hyper-rectangle of packets matched by rule r; since r’s predicate is itself interval-based (Definition 1’s remark), H(r) is a single hyper-rectangle, but its intersection with the ROIDD’s single-interval edges (O4) at a given node, I(e) ∩ H(r)[F(v)], may still split into several sub-intervals when H(r)’s interval partially overlaps more than one edge; Algorithm 2’s traversal below visits every such reachable edge, so this case is handled without special-casing.
Definition 12 (Shadow).
A rule r in layer L is shadowed if there exists no packet p ∈ U such that r determines ⟦Π⟧(p)—i.e., r’s contribution is always overridden by higher-priority rules or by deny rules in the same layer.
Definition 13 (Redundancy).
A rule r in layer L is redundant if removing r from L yields Πʹ with ⟦Πʹ⟧ = ⟦Π⟧. Removing r does not change the composite policy for any packet.
Definition 14 (Cross-Layer Conflict).
Rules r ∈ L1 and rʹ ∈ L2, L1≠ L2, are in cross-layer conflict if ∃ p matching both r and rʹ with action(r) ≠ action(rʹ). This is a policy intent flag: deny-wins resolves it at runtime, but the administrator may not have intended the override.
Definition 15 (Unreachable Region).
A hyper-rectangle H ⊆ U is an unreachable region if ⟦Π⟧(p) = deny for all p ∈ H and no rule in any layer explicitly denies H—the deny arises solely from default-deny, indicating an unintentional gap in the allow-list.
Algorithm 2 (Shadow Detection).
Input: Π, ROIDD(Π, π). Output: Set of shadowed rules.
1: Compute H(r) the hyper-rectangle of packets matched by r.
2: Traverse the ROIDD restricting at each node v to I(e) ∩ H(r)[F(v)]. Collect all reachable terminal nodes.
3: If no terminal exists where r determines the composite action, output r as shadowed.

Complexity: O(|ROIDD|·|rules|); faster in practice due to early pruning on empty intersections.


Theorem 4 (Shadow Detection: Soundness & Completeness).
Algorithm 2 reports r as shadowed if and only if r is shadowed (Definition 12).
Proof. (⇒ Soundness) If Algorithm 2 reports r shadowed, no terminal in H(r) has r as the determining rule. By Theorem 2, ⟦Π⟧(p) is determined by other rules for all p ∈ H(r); hence r is shadowed. (⇐ Completeness) If r is shadowed, the ROIDD (Theorem 2) reflects the overriding action at every terminal reachable under H(r). Algorithm 2’s traversal is exhaustive over all such paths, so it finds no terminal where r determines the outcome. □
Algorithm 3 (Redundancy Detection).
Input: Π, ROIDD(Π, π). Output: Set of redundant rules.
1: For each rule r ∈ L, build Πʹ = Π with r removed (incremental delta update on H(r)).
2: Build ROIDD(Πʹ, π).
3: If ROIDD(Π, π) ≅ ROIDD(Πʹ, π), output r as redundant.

Complexity: O(|rules|) ROIDD rebuilds, each O(|G|·|F| + |ROIDD| log |ROIDD|) in the worst case (Algorithm 1), for a total of O(|rules|·|G|·|F|). A certified incremental DD-update scheme—recomputing only the subdiagram touched by H(r) rather than rebuilding from scratch—could reduce this to O(|ROIDD|) amortized per rule; we report the worst-case rebuild cost here and leave a certified incremental construction to future work.
Theorem 5 (Redundancy Detection: Soundness & Completeness).
Algorithm 3 reports r as redundant if and only if r is redundant (Definition 13). Proof: Corollary 2 gives ROIDD(Π, π) ≅ ROIDD(Πʹ, π) iff ⟦Π⟧ = ⟦Πʹ⟧ iff removing r does not change the composite policy iff r is redundant. □
Algorithm 4 (Cross-Layer Conflict & Unreachable Region Detection).
Input: Π, ROIDD(Π, π). Output: Conflict pairs; unreachable hyper-rectangles.
Cross-layer conflicts: for each pair (r ∈ L1, rʹ ∈ L2) with L1≠ L2:
(1) Compute H(r) ∩ H(rʹ). If empty, skip. (2) If action(r) ≠ action(rʹ), record (r, rʹ) as a cross-layer conflict.
Unreachable regions: for each terminal node t labelled deny in the ROIDD:
(1) Reconstruct H(t) from the root-to-t path. (2) Check whether any rule in any layer explicitly denies H(t). (3) If none, record H(t) as an unreachable region.

Complexity: O(|rules|2) cross-layer; O(|ROIDD|·|rules|) unreachable regions.
Theorem 6 (Algorithm 4: Soundness & Completeness).
Algorithm 4 reports (r, rʹ) as a cross-layer conflict iff they satisfy Definition 14; reports H as an unreachable region iff H satisfies Definition 15. Proof: Cross-layer conflicts: the intersection check is exact (interval arithmetic) and the action comparison is direct; exhaustion over all rule pairs gives soundness and completeness. Unreachable regions: every terminal t labelled deny in the ROIDD corresponds to a non-empty cell H(t) (by O5, O6 of Definition 9). Theorem 2 ensures ⟦Π⟧(p) = deny for all p ∈ H(t). The check against all layer rules is exhaustive; if none matches, the deny is default-deny only. □
Table 2 summarizes the four anomaly types and their certified detection algorithms.

6. Evaluation

6.1. Experimental Setup

We implemented the ROIDD construction (Algorithm 1) and all detection algorithms (Algorithms 2–4) as a Python reference implementation (CPython 3.12.10) using only the standard library, with an additional native C++17 implementation of ROIDD construction and lookup described in Section 6.8. Experiments were conducted on a single machine—an Intel Core 5 210H processor (2.20 GHz), 32 GB RAM, Windows 11 (build 26200), CPython 3.12.10, and g++ 13 (MSYS2 UCRT64) at -O2—so the Python-versus-C++ comparison in Section 6.8 isolates the effect of the implementation language. Field domains were set to 4 label classes, 2 protocols, 8 port buckets, and 4 IP prefix groups per field, giving a product grid of 4×4×2×8×8×4×4 = 32,768 cells—small enough to be tractable in pure Python while faithfully capturing all structural properties proven in Section 3, Section 4 and Section 5. Synthetic policies were generated with a randomized generator that permits controlled injection of shadow and redundant anomalies. Results are reported across five independent trials per experiment.

6.2. Experiment 1: Correctness Validation

We verified ⟦ROIDD⟧(p) = ⟦Π⟧(p) for all tested packets using two harnesses in tandem: (a) 2,000 uniformly random packets per configuration, and (b) exhaustive enumeration over the Cartesian product of the first three fields (Fslabel, Fdlabel, Fproto), producing 32 additional test cases per configuration. Table 3 reports zero mismatches across all five configurations (5–22 rules, 2,032 packets each), validating Theorem 2. DAG sharing ratios range from 3.8× (tiny, 5 rules) to 11.9× (large, 17 rules), increasing with policy complexity as rule interactions create more shareable sub-diagrams.

6.3. Experiment 2: Scalability

Table 4 reports ROIDD build time and per-packet lookup latency as the total rule count grows from 4 to 38 rules. Three key observations: (1) DAG compression ratios range from 5.1× to 15.4×, confirming that policy complexity drives sharing rather than suppressing it. (2) Per-packet lookup latency stays at 0.56–1.52 µs regardless of policy size, consistent with the O(|F|) = O(7) traversal depth guaranteed by Definition 9—low-microsecond lookup is achievable even in pure Python. (3) Build time grows from 64 ms (4 rules) to 848 ms (38 rules) in the Python reference; the native C++ implementation constructs the same diagrams 21–65× faster and classifies packets 26–35× faster (Section 6.8), confirming that the sub-microsecond latency is intrinsic to the algorithm.

6.4. Experiment 3: Conflict Detection Accuracy

We injected exactly 2 shadow rules and 2 redundant rules into each trial policy and compared the detected count against a clean-baseline run of the same policy (no injection). The delta (Δ = detected − baseline) measures sensitivity to injected anomalies. Table 5 shows that the mean Δ across 5 trials is 6.0 for shadow and 6.0 for redundancy, confirming that all injected anomalies—and additional naturally-occurring ones—are faithfully detected. Deltas above 2 (e.g., Trial 4: Δshadow = 10) arise because injecting a rule into an already-anomalous region can cascade, producing additional shadows beyond the directly injected one. This behavior is consistent with the completeness guarantees of Theorems 4 and 5: the algorithms detect all anomalies, not only the injected ones. Cross-layer conflicts and unreachable regions are also detected automatically as natural structural properties of the random policies.

6.5. Experiment 4: Equivalence Oracle

We validated Corollary 2 by constructing pairs of identical policies (same random seed → identical ROIDD, expected isomorphic) and pairs of distinct policies (different seeds → distinct forwarding function, expected non-isomorphic). Table 6 confirms 100% accuracy across all 5 trials. A notable asymmetry appears in timing: confirming that two ROIDDs are identical requires full traversal (mean 453.7 µs), whereas detecting that they are different terminates at the first structural divergence (mean 3.0 µs)—a 149× speedup. This fail-fast behavior is particularly valuable in CI/CD policy linting, where most policy comparisons involve genuinely different configurations.

6.6. Experiment 5: Field-Order Sensitivity

Table 7 compares ROIDD sizes under five field orderings for the same 17-rule policy. ROIDD node counts range from 115 (reversed) to 173 (dport_first)—a 1.5× range—while correctness is zero under every ordering. This confirms that field order affects only DAG size, not semantic correctness or the equivalence-oracle property (Theorem 3). The slabel_first default achieves the highest compression ratio of 21.63×, supporting the heuristic of placing identity-based fields (label) early in the ordering (Section 4.3), since many policies partition primarily by endpoint identity and large subtrees can be shared across port/protocol combinations.

6.7. Threats to Validity

Domain compression. Domains are compressed to make the 32,768-cell grid tractable in Python. The analytical proofs (Theorems 1–6) are domain-size independent; build time and absolute ROIDD node counts will scale in production. A C++/eBPF implementation is left to future work.
Synthetic policies. Policies were generated randomly. Real cluster policies may exhibit different label distributions, port concentrations, and cross-layer interaction patterns. The proofs are unconditional; representative compression ratios and detection times may differ in production environments.
CVE-2024-47825. [1] documents a bug where CIDR deny policies may not take effect under specific combinations of narrow CIDR allow rules and enableDefaultDeny: false. Our formal model captures the intended semantics as documented; this CVE is precisely the kind of implementation divergence that a tool based on our model can detect by comparing the intended composite policy (as represented in the ROIDD) against observed eBPF forwarding behavior.

6.8. Native Implementation and Language Comparison

To determine whether the low-microsecond lookup latency of Section 6.3 is intrinsic to the ROIDD or an artifact of the Python interpreter, we reimplemented ROIDD construction and lookup in C++17. Both implementations read the identical policy dataset and produced identical decision-diagram structures—the same ROIDD node counts, tree-node counts, and sharing ratios for all thirteen configurations (Table 3 and Table 4)—confirming that they realize the same canonical diagram, as guaranteed by Theorem 3. Because the structures are identical, the comparison in Table 8 isolates the cost of the implementation language alone.
The native implementation classifies a packet in 16–43 ns on average (21–57 ns at the 99th percentile), a 26–35× speedup over the Python reference, and constructs the diagram 21–65× faster. Every configuration stays well below 100 ns per lookup—comfortably within the latency budget of eBPF-based enforcement—showing that sub-microsecond classification is a property of the algorithm rather than of any one language. The shared dataset, both implementations, and reproduction instructions are publicly available (see the Data Availability Statement).

7. Discussion

7.1. Practical Deployment

The ROIDD framework is well suited for integration into a CI/CD pipeline as a policy linter: before deploying a new policy configuration, the ROIDD is built and the four detection algorithms are run. A zero-conflict report provides a formal guarantee (via Theorems 4–6) that no shadows, redundancies, cross-layer conflicts, or default-deny gaps exist. The equivalence oracle (Corollary 2) can additionally be used to verify that a policy refactoring did not inadvertently change forwarding behavior.
Per-packet lookup at 0.56–1.52 µs is comfortably below the latency budget of eBPF-based enforcement, suggesting that an eBPF-compiled ROIDD could serve as a fast-path policy evaluator alongside the existing Cilium datapath, with the full ROIDD stored in a BPF map.

7.2. Extension to L7 and Multi-Cluster

The current model is restricted to L3/L4 packet fields. Cilium’s L7 proxy policies (HTTP methods, gRPC routes, Kafka topics) operate at a different abstraction level and require a different canonical form—likely a tree-structured regular-expression automaton rather than an interval DD. We leave this extension to future work. Similarly, ClusterMesh policies span multiple control planes; their composition semantics requires a multi-cluster generalization of Definition 7 that we also leave for future work.

7.3. Generalization to Other CNIs

The three-layer composition framework (additive + deny-wins + cluster-override) is not Cilium-specific: Calico supports a similar structure with GlobalNetworkPolicy acting as cluster-override. The ROIDD construction and the canonicity theorem require only that each layer’s semantics be HRPC-like (Theorem 1), a property that holds for any finite-rule, interval-predicate policy language. We conjecture that the framework applies directly to Calico and with minor modifications to other CNIs (Antrea, Weave) that support explicit deny rules.

8. Conclusion

We have presented the first formal decision-diagram framework for conflict detection in Cilium’s three-layer network policy model. Our three contributions—(C1) HRPC-like composite semantics with Theorem 1, (C2) canonical ROIDD with the Myhill–Nerode canonicity theorem, and (C3) certified shadow/redundancy/conflict/unreachable-region detection algorithms with soundness and completeness proofs—collectively provide the formal foundation that existing tools (KANO, VeriKube, VDM-SL) lack. Experimental evaluation confirms zero correctness mismatches, ROIDD compression ratios of 5–15×, low-microsecond per-packet lookup, and correct equivalence-oracle behavior in all trials.
The framework is immediately applicable as a CI/CD policy linter and as a foundation for certified Cilium policy refactoring. Future work includes L7 and multi-cluster extensions, production-scale C++ implementation, and generalization to other CNIs including Calico and Antrea.

Author Contributions

Conceptualization, T.C.; methodology, T.C.; software, T.C. and S.P.; validation, T.C. and S.P.; formal analysis, T.C.; investigation, T.C. and S.P.; writing—original draft preparation, T.C.; writing—review and editing, S.P.; funding acquisition, S.P. All authors have read and agreed to the published version of the manuscript.

Funding

This research received no external funding.

Institutional Review Board Statement

Not applicable.

Data Availability Statement

The source code, experimental scripts, complete results, and reproduction instructions supporting this study are openly available on GitHub at https://github.com/thawatchai2799/cilium_20260702_2329 (accessed on 3 July 2026), and archived at Zenodo, DOI: 10.5281/zenodo.21141430.

Acknowledgments

The author thanks the Faculty of Informatics, Mahasarakham University, for computational resources and continued support.

Conflicts of Interest

The authors declare no conflicts of interest.

References

  1. Cilium Project. Cilium’s CIDR Deny Policies May Not Take Effect When a More Narrow CIDR Allow Is Present. Available online: https://github.com/cilium/cilium/security/advisories/GHSA-3wwx-63fv-pfq6 (accessed on October 2024).
  2. Datadog Engineering. Why CiliumNetworkPolicy Rules Block Traffic in Kubernetes Clusters. Available online: https://www.datadoghq.com/blog/cilium-network-policy-misconfigurations/ (accessed on December 2025).
  3. Li, Y.; Jia, C.; Hu, X.; Li, J. Kano: Efficient container network policy verification. In Proceedings of the 2020 IEEE Symposium on High-Performance Interconnects (HOTI), Santa Clara, CA, USA, August 2020; pp. 63–70. [CrossRef]
  4. Kang, H.; Shin, S. VeriKube: Automatic and efficient verification for container network policies. IEICE Trans. Inf. Syst. 2022, E105-D, 2131–2134. [CrossRef]
  5. Kulik, T.; Boudjadar, J. Cilium and VDM—Towards formal analysis of Cilium policies. arXiv 2024, arXiv:2410.12009.
  6. Cilium Project. Deny Policies. Cilium Documentation, Version 1.19. Available online: https://docs.cilium.io/en/stable/security/policy/deny/ (accessed on June 2026).
  7. Cilium Project. Network Policy. Cilium Documentation, Version 1.19. Available online: https://docs.cilium.io/en/stable/network/kubernetes/policy/ (accessed on June 2026).
  8. Cilium Project. Policy Enforcement Modes. Cilium Documentation, Version 1.19. Available online: https://docs.cilium.io/en/stable/security/policy/intro/ (accessed on June 2026).
  9. Gouda, M.G.; Liu, A.X. Structured firewall design. Comput. Netw. 2007, 51, 1106–1120. [CrossRef]
  10. Gouda, M.G.; Liu, A.X. Diverse firewall design. IEEE Trans. Parallel Distrib. Syst. 2008, 19, 1237–1251. [CrossRef]
  11. Al-Shaer, E.; Hamed, H. Discovery of policy anomalies in distributed firewalls. In Proceedings of the IEEE INFOCOM 2004, Hong Kong, China, March 2004; Volume 4, pp. 2605–2616. [CrossRef]
  12. Yu, M.; Li, F.; Yu, N.; Wang, X.; Guo, Y. Detecting conflict of heterogeneous access control policies. Digit. Commun. Netw. 2022, 8, 664–679. [CrossRef]
  13. Chomsiri, T.; He, X.; Nanda, P.; Tan, Z. Hybrid Tree-Rule Firewall for high speed data transmission. IEEE Trans. Cloud Comput. 2020, 8, 1237–1249. [CrossRef]
  14. Chomsiri, T.; He, X.; Nanda, P. Limitation of listed-rule firewall and the design of Tree-Rule Firewall. In Internet and Distributed Computing Systems, Proceedings of the 5th International Conference on Internet and Distributed Computing Systems (IDCS 2012), Wuyishan, China, 21–23 November 2012; Xiang, Y., Pathan, M., Tao, X., Wang, H., Eds.; Lecture Notes in Computer Science; Springer: Berlin/Heidelberg, Germany, 2012; Volume 7646, pp. 275–287. [CrossRef]
  15. He, X.; Chomsiri, T.; Nanda, P.; Tan, Z. Improving cloud network security using the Tree-Rule firewall. Future Gener. Comput. Syst. 2014, 30, 116–126. [CrossRef]
  16. Booth, R.; Noisanguan, W. An axiomatic approach to firewall rule update. In Proceedings of the 6th International Joint Conference on Computer Science and Software Engineering (JCSSE 2009), Phuket, Thailand, May 2009.
  17. Booth, R.; Chandler, J. On strengthening the logic of iterated belief revision: Proper ordinal interval operators. Artif. Intell. 2020, 285, 103289. [CrossRef]
  18. Bryant, R.E. Graph-based algorithms for Boolean function manipulation. IEEE Trans. Comput. 1986, C-35, 677–691. [CrossRef]
Table 1. Comparison with existing work on container/firewall policy verification.
Table 1. Comparison with existing work on container/firewall policy verification.
Work Cilium multi-layer Formal
semantics
Canonical form Conflict
+proof
Equiv. oracle
KANO [3] KNP only No Bit-matrix No No
VeriKube [4] Partial No Novel graph No No
VDM-SL [5] CNP only Partial No No No
FDD [9] LR only Yes Yes Yes Yes
This work All three Yes (Thm. 1) Yes (ROIDD) Yes Yes
Table 2. Summary of anomaly types, detection algorithms, and correctness theorems.
Table 2. Summary of anomaly types, detection algorithms, and correctness theorems.
Anomaly Layer scope Algorithm Theorem
Shadow Single- or cross-layer Algorithm 2 Theorem 4
Redundancy Single-layer Algorithm 3 Theorem 5
Cross-layer conflict Cross-layer Algorithm 4 Theorem 6
Unreachable region Composite (all layers) Algorithm 4 Theorem 6
Table 3. Correctness experiment: all mismatches are zero (Theorem 2 validated). Python 3.12.10.
Table 3. Correctness experiment: all mismatches are zero (Theorem 2 validated). Python 3.12.10.
Config Rules ROIDD nodes Tree nodes Sharing ratio Build (ms) Mismatches
tiny 5 27 103 3.81× 70 0
small 9 62 515 8.31× 128 0
medium 12 82 805 9.82× 322 0
large 17 110 1313 11.94× 372 0
xlarge 22 172 1903 11.06× 423 0
Table 4. Scalability: ROIDD compression ratio and per-packet lookup latency as rule count grows.
Table 4. Scalability: ROIDD compression ratio and per-packet lookup latency as rule count grows.
Total rules ROIDD nodes Tree nodes Ratio Build (ms) Lookup (µs)
4 28 143 5.11× 64 0.56
8 58 416 7.17× 71 0.82
12 78 943 12.09× 203 0.86
17 128 1886 14.73× 407 1.06
22 140 1748 12.49× 548 1.13
27 174 2003 11.51× 624 1.09
32 163 2227 13.66× 754 1.14
38 366 5636 15.40× 848 1.52
Table 5. Conflict detection: Δ = detected−baseline. Mean Δshadow = 6.0, mean Δredundant = 6.0 across 5 trials.
Table 5. Conflict detection: Δ = detected−baseline. Mean Δshadow = 6.0, mean Δredundant = 6.0 across 5 trials.
Trial Shadow (base→total, Δ) Redundant (base→total, Δ) Conflicts Unreachable Time (ms)
1 2→7 (Δ5) 1→6 (Δ5) 3 271 6036
2 3→7 (Δ4) 2→6 (Δ4) 11 305 3534
3 1→8 (Δ7) 0→7 (Δ7) 11 472 4498
4 1→11 (Δ10) 0→11 (Δ11) 21 58 3746
5 4→8 (Δ4) 3→6 (Δ3) 5 316 2058
Table 6. Equivalence oracle: 100% accuracy in 5 trials (Corollary 2 validated). Mean same-iso = 453.7 µs, diff-iso = 3.0 µs.
Table 6. Equivalence oracle: 100% accuracy in 5 trials (Corollary 2 validated). Mean same-iso = 453.7 µs, diff-iso = 3.0 µs.
Trial same_iso Time (µs) diff_iso Time (µs) correct_same correct_diff
1 True 372.1 False 1.9 True True
2 True 370.2 False 5.1 True True
3 True 380.6 False 2.1 True True
4 True 384.5 False 4.3 True True
5 True 761.2 False 1.8 True True
Table 7. Field-order sensitivity: ROIDD size varies by 1.5× across orderings; correctness is invariant (0 mismatches).
Table 7. Field-order sensitivity: ROIDD size varies by 1.5× across orderings; correctness is invariant (0 mismatches).
Field order ROIDD nodes Tree nodes Ratio Build (ms) Mismatches
slabel_first (default) 161 3483 21.63× 498 0
dport_first 173 2556 14.77× 501 0
ip_first 128 1250 9.77× 499 0
label_dport_first 136 2426 17.84× 500 0
reversed 115 898 7.81× 495 0
Table 8. Reference (Python) versus native (C++) implementation on identical inputs and identical hardware (Intel Core 5 210H, CPython 3.12.10, g++ 13 at -O2). ROIDD node counts are identical between the two implementations; only build time and lookup latency differ. Lookup latency is the per-packet mean.
Table 8. Reference (Python) versus native (C++) implementation on identical inputs and identical hardware (Intel Core 5 210H, CPython 3.12.10, g++ 13 at -O2). ROIDD node counts are identical between the two implementations; only build time and lookup latency differ. Lookup latency is the per-packet mean.
Config Rules Nodes Build Py (ms) Build C++ (ms) Lookup Py (ns) Lookup C++
(ns)
Speedup
tiny 5 27 70.4 3.2 579.6 16.5 35×
small 9 62 128.1 4.0 681.7 23.0 30×
medium 12 82 322.5 8.9 813.7 28.8 28×
large 17 110 372.4 7.7 889.2 31.5 28×
xlarge 22 172 423.3 8.5 944.5 34.3 28×
scale-4 4 28 64.5 3.1 554.1 15.9 35×
scale-8 8 58 70.8 2.4 776.9 24.6 32×
scale-12 12 78 203.0 5.7 816.7 27.3 30×
scale-17 17 128 407.3 9.3 951.1 33.4 28×
scale-22 22 140 548.3 11.3 945.0 35.6 27×
scale-27 27 174 623.5 11.4 923.3 34.0 27×
scale-32 32 163 754.0 14.4 953.4 33.8 28×
scale-38 38 366 847.5 13.0 1130.1 43.4 26×
Disclaimer/Publisher’s Note: The statements, opinions and data contained in all publications are solely those of the individual author(s) and contributor(s) and not of MDPI and/or the editor(s). MDPI and/or the editor(s) disclaim responsibility for any injury to people or property resulting from any ideas, methods, instructions or products referred to in the content.
Copyright: This open access article is published under a Creative Commons CC BY 4.0 license, which permit the free download, distribution, and reuse, provided that the author and preprint are cited in any reuse.
Prerpints.org logo

Preprints.org is a free preprint server supported by MDPI in Basel, Switzerland.

Subscribe

© 2026 MDPI (Basel, Switzerland) unless otherwise stated

Accessibility

Disclaimer

Terms of Use

Privacy Policy

Privacy Settings