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

   ### Test report: IPv6 protocol-number ACL rules on a running VPC router, 
with extension-header traffic
   
   **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:
     - Main still ships system VM template 4.22.0, and the IPv6 ACL part of 
`configure.py` is the same on 4.22 and main.
     - 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). The router was created 
on this build, and its `/opt/cloud/bin/configure.py` matches the build's (md5 
checked before and after every stock-script comparison).
   - A dual-stack VPC. Tier T1 holds V1 (Ubuntu 24.04), which listens on UDP 
5001 and runs `tcpdump` on its NIC.
   - An external host on the public network sends the probe packets with scapy 
2.5.0.
   - Each stage had **only one rule** in T1's list, so every delivered packet 
can be tied to that rule. Each rule is `cidrlist=::/0 action=allow`, ingress 
unless stated.
   - For the "without the PR" runs, I copied apache/main's `configure.py` onto 
the router, re-applied the list, and then restored the PR's script with 
`restartVPC livepatch=true`.
   
   **1. What the router renders**
   
   | Rule protocol | With the PR | Stock |
   |---|---|---|
   | 17 | `meta l4proto udp accept` | `ip6 nexthdr udp accept` |
   | 6 | `meta l4proto tcp accept` | |
   | 60 (destination options) | `exthdr dst exists accept` | `ip6 nexthdr 
ipv6-opts accept` |
   | 0 (hop-by-hop) | `exthdr hbh exists accept` | |
   | 51 (AH) | `meta l4proto ah accept` | `ip6 nexthdr ah accept` |
   
   Every rule loaded. The router's `cloud.log` has no failed `nft add` line 
over the whole run.
   
   **2. Ingress traffic (external host to V1)**
   
   | Rule | Packet | With the PR | Stock |
   |---|---|---|---|
   | 17 | `IPv6/UDP` | delivered | delivered |
   | 17 | `IPv6/DestOpt/UDP` | **delivered** | **dropped** |
   | 17 | `IPv6/HopByHop/UDP` | **delivered** | **dropped** |
   | 17 | `IPv6/AH/UDP` | dropped | dropped |
   | 17 | `IPv6/TCP` SYN | dropped | |
   | 60 | `IPv6/DestOpt/UDP` | delivered | delivered |
   | 60 | `IPv6/UDP`, `IPv6/HopByHop/UDP` | dropped | dropped (UDP) |
   | 0 | `IPv6/HopByHop/UDP` | delivered | |
   | 0 | `IPv6/UDP`, `IPv6/DestOpt/UDP` | dropped | |
   | 51 | `IPv6/AH/UDP`, `IPv6/AH` (no next header) | delivered | delivered |
   | 51 | `IPv6/UDP` | dropped | dropped |
   | 6 | `IPv6/TCP` SYN | delivered (V1 answers with a reset) | |
   | 6 | `IPv6/UDP` | dropped | |
   
   From V1's capture, with the PR and rule 17 only:
   ```
   IP6 (next-header unknown (60) ...) <ext> > <V1>: DSTOPT (padn) 41002 > 5001: 
[udp sum ok] UDP, length 3
   IP6 (next-header Options (0) ...) <ext> > <V1>: HBH (padn) 41006 > 5001: 
[udp sum ok] UDP, length 3
   ```
   With the stock script and the same rule, only the plain UDP packet arrives.
   
   - Protocol 51 behaves the same with and without the PR. nft's `meta l4proto` 
stops at an AH header, so `meta l4proto ah` matches AH packets, and a UDP rule 
does not match UDP carried behind AH.
   - With the PR and rules 17, 60 and 51 in one list, the UDP, 
destination-options, hop-by-hop and AH packets are all delivered, and a TCP SYN 
and an ICMPv6 echo are dropped.
   
   **3. Egress traffic (V1 to the external host)**
   
   V1 sends a plain UDP datagram and one with a destination options header 
(`IPV6_DSTOPTS` socket option). The capture runs on the external host.
   
   | Egress rule | Plain UDP | DestOpt/UDP |
   |---|---|---|
   | 17, with the PR (`ip6 daddr ::/0 meta l4proto udp accept`) | delivered | 
**delivered** |
   | 17, stock (`ip6 daddr ::/0 ip6 nexthdr udp accept`) | delivered | 
**dropped** |
   | 60, with the PR (`exthdr dst exists accept`) | dropped | delivered |
   
   **4. Restore**
   
   After `restartVPC livepatch=true`, the router's `configure.py` matched the 
build again. Rule 17 rendered `meta l4proto udp` again, and the 
destination-options UDP packet was delivered again.
   
   **Result:** pass.
   - Protocol-number rules render as `meta l4proto <n>`, and extension-header 
numbers render as `exthdr <name> exists`. Everything loads on nft 1.0.6.
   - A UDP rule given as protocol 17 now matches UDP behind a destination 
options or hop-by-hop header, ingress and egress. The stock script drops those 
packets.
   - Extension-header rules match their header, and nothing else.
   
   **Not covered**
   - Routing (43), fragment (44) and mobility (135) headers. Only the mapping 
for 0 and 60 was exercised on traffic. 43, 44 and 135 come from the same table 
in the code.
   - Redundant VPC routers, and templates older than 4.22.0.
   


-- 
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