Question
Implement an ordered firewall policy for IPv4 addresses. ```python def allow_access(rules: list, ip: str) -> bool: ... ``` Each rule is `[action, cidr]`, where `action` is `"ALLOW"` or `"DENY"`. Evaluate rules from top to bottom; the first network containing the address determines the result. If no rule matches, deny access. A rule without a prefix length represents one address, equivalent to `/32`. ## Requirements - Parse and validate dotted-decimal IPv4 addresses and CIDR prefix lengths. - Correctly handle `/0`, `/32`, network boundaries, and overlapping rules. - Preserve first-match semantics; a more specific later rule does not override an earlier match. - Raise `ValueError` for malformed input, including malformed rules after an earlier matching rule. Validate the complete policy before deciding access. IPv4 uses exactly four ASCII decimal octets in 0–255 without leading zeros, signs or whitespace; CIDR prefix is an ASCII decimal integer in 0–32. Host bits in the CIDR base are masked, not rejected. Unknown actions are invalid. Valid rules are a list of two-element lists or tuples. - Do not modify the policy. `_ipv4` and `_cidr_match` are optional helpers; the assessed interface is `allow_access`. The supplied `run_case` is fixture glue. ## Design discussion (not graded) 1. Support IPv6 without duplicating policy logic. 2. Compile a large static rule list for high-throughput lookup while preserving order. 3. Return the matching rule and an audit explanation. 4. Support safe, atomic policy updates in a concurrent service.