bhouse-nexthop commented on PR #14357:
URL: https://github.com/apache/cloudstack/pull/14357#issuecomment-6727080322

   ### Test report: protocol-number and upper-case ICMP rules, and the six 
partial-update cases
   
   This adds to @Damans227's test (protocol 6 and 17, ICMP 8/0, egress, a 
reboot). It covers the residual cases, plus @weizhouapache's six partial-update 
scenarios run against a live management server and router.
   
   **Environment**
   - A CloudStack 24.0 (main) build with this PR applied, alongside some of my 
other open PRs.
   - Why the result carries over to 4.22:
     - The PR's changes are on the management server (`NetworkACLServiceImpl`, 
the create and update commands, `SetNetworkACLCommand`, `NetUtils`), and they 
apply cleanly to main.
     - The router side is system VM template 4.22.0, as on 4.22.
     - The VPC offering has no Firewall service, as on 4.22.
   - Three KVM hosts on Ubuntu 24.04, nested virtualisation; Ceph RBD primary 
storage.
   - System VM template 4.22.0 (Debian 12, nft 1.0.6).
   - A dual-stack VPC: tier T1 holds the server V1, with the test list; tier T2 
holds the client V2. There is also an external IPv6 host.
   
   **1. Rendering on the router**
   
   | Rule (API) | Stored | Router |
   |---|---|---|
   | `protocol=ICMP icmptype=3 icmpcode=1`, 0.0.0.0/0 | `ICMP` 3/1 | `-p icmp 
-m icmp --icmp-type 3/1 -j ACCEPT` |
   | `protocol=ICMP icmptype=3 icmpcode=1` from the external /64, then `update 
protocol=1 icmptype=128 icmpcode=0` | `icmp` 128/0 | `ip6 saddr fd00:30::/64 
icmpv6 type echo-request icmpv6 code no-route accept`. ping6 from the external 
host to V1: 2/2 |
   | `protocol=tcp` (no ports), then `update protocol=icmp` with no type or 
code | `icmp`, type and code null | `-p icmp -m icmp --icmp-type any -j 
ACCEPT`. ping from V2: 2/2 |
   | `protocol=006 startport=22 endport=22` | `006` 22-22 | `-p tcp -m tcp 
--dport 22 -j ACCEPT`. tcp 22 from V2 connects, tcp 8080 does not |
   
   No ACL apply failed: the agent log on the router's host has no `ruleParts` 
or `Problem occurred` line after these changes.
   
   **2. The six partial-update cases, default `partialupgrade=true`**
   
   Each case starts from a fresh rule from T2's CIDR with action allow: either 
tcp 80-80 or icmp 8/0.
   
   | # | Stored | Update | Result | Rule afterwards |
   |---|---|---|---|---|
   | 1 | tcp 80-80 | `protocol=icmp` | rejected: "Can't specify start/end port 
when protocol is ICMP" | tcp 80-80 (unchanged) |
   | 2 | tcp 80-80 | `protocol=udp` | accepted | udp 80-80 (ports kept) |
   | 3 | tcp 80-80 | `protocol=udp startport=53 endport=53` | accepted | udp 
53-53 |
   | 4 | icmp 8/0 | `protocol=tcp` | rejected: "Can specify icmpCode and 
icmpType for ICMP protocol only" | icmp 8/0 (unchanged) |
   | 5 | icmp 8/0 | `protocol=tcp icmptype=8` | rejected, same message | icmp 
8/0 (unchanged) |
   | 6 | icmp 8/0 | `protocol=1 icmptype=0 icmpcode=0` | accepted | icmp 0/0 |
   
   This matches the table in the review thread: rejected / ports kept / new 
ports / rejected / rejected / new type.
   
   **3. The same cases with `partialupgrade=false`**
   
   When `cidrlist`, `action` and `traffictype` are passed as well, every field 
is replaced from the call:
   
   | # | Update | Rule afterwards |
   |---|---|---|
   | 1 | `protocol=icmp` | icmp, type/code -1 (all ICMP), no ports |
   | 2 | `protocol=udp` | udp, no ports |
   | 3 | `protocol=udp startport=53 endport=53` | udp 53-53 |
   | 4 | `protocol=tcp` | tcp, no ports, no ICMP type |
   | 5 | `protocol=tcp icmptype=8` | accepted; tcp, the `icmptype=8` silently 
dropped |
   | 6 | `protocol=1 icmptype=0 icmpcode=0` | icmp 0/0 |
   
   **Not part of this PR, but worth knowing.** A `partialupgrade=false` call 
that leaves out `cidrlist`, `action` or `traffictype` breaks the rule. The 
update fails with:
   ```
   Cannot invoke "java.util.List.size()" because "cidrs" is null      
(NetworkACLItemCidrsDaoImpl.updateCidrs)
   ```
   - By then, `NetworkACLItemDaoImpl.update()` has already written the row with 
those fields set to null.
   - `listNetworkACLs` for that list then fails with `Cannot invoke 
"...TrafficType.toString()" because ... getTrafficType() is null`, until the 
rule is updated again with every field.
   
   That path (`transferDataToNetworkAclRulePojo()` and the DAO update) is the 
same on main without this PR. This PR only adds its port check ahead of it, so 
it is an existing bug, and it should get an issue of its own. It does mean that 
`partialupgrade=false` is a "clean replace" only when the caller passes every 
field. That corrects what I said in my reply in the review thread, where I 
described it as a clean replace without that condition.
   
   **Result:** pass, against the residual cases and the six-case table.
   
   **Not covered**
   - The UI: the start and end port fields in the ACL rule form.
   - A router with an older template.
   - Egress ICMP rules.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to