@@ -743,6 +743,56 @@ Actions (superset of shutdown):
743743> are NOT removed on destroy — they may still be used by other networks or for
744744> VM connectivity.
745745
746+ ### VPC lifecycle commands: ` implement-vpc ` , ` shutdown-vpc ` , ` destroy-vpc `
747+
748+ These commands manage VPC-level state. Called by ` NetworkExtensionElement ` when
749+ implementing, shutting down, or destroying a VPC (before or after per-tier
750+ network operations).
751+
752+ #### ` implement-vpc `
753+
754+ ```
755+ network-namespace-wrapper.sh implement-vpc \
756+ --vpc-id <vpc-id> \
757+ --cidr <vpc-cidr>
758+ ```
759+
760+ Actions:
761+ 1 . Create the shared VPC namespace ` cs-vpc-<vpc-id> ` .
762+ 2 . Enable IP forwarding inside the namespace.
763+ 3 . Create iptables chains for NAT and filter rules.
764+ 4 . Save VPC metadata (CIDR, gateway) to state files under ` /var/lib/cloudstack/<ext-name>/vpc-<vpc-id>/ ` .
765+
766+ > This command runs ** before** any tier networks are implemented. Tier networks
767+ > inherit the same namespace and host assignment.
768+
769+ #### ` shutdown-vpc `
770+
771+ ```
772+ network-namespace-wrapper.sh shutdown-vpc \
773+ --vpc-id <vpc-id>
774+ ```
775+
776+ Actions:
777+ 1 . Flush all iptables rules (ingress, egress, NAT chains inside the namespace).
778+ 2 . Stop all services (dnsmasq, haproxy, apache2, password-server) for all tiers.
779+ 3 . Keep the namespace and tier veths intact (tiers may restart).
780+
781+ > Called when the VPC is shut down; tier networks may be restarted later.
782+
783+ #### ` destroy-vpc `
784+
785+ ```
786+ network-namespace-wrapper.sh destroy-vpc \
787+ --vpc-id <vpc-id>
788+ ```
789+
790+ Actions:
791+ 1 . Remove the entire namespace ` cs-vpc-<vpc-id> ` (deletes all interfaces inside).
792+ 2 . Remove VPC-wide state directory ` /var/lib/cloudstack/<ext-name>/vpc-<vpc-id>/ ` .
793+
794+ > This is the final cleanup step; after this, the VPC namespace is gone.
795+
746796### ` assign-ip `
747797
748798Called when a public IP is associated with the network (including source NAT).
@@ -929,6 +979,55 @@ iptables design (two independent parts, both inside the namespace):
929979 ` default_egress_allow ` policy (allow-by-default or deny-by-default) to VM
930980 outbound traffic on ` -i vn-<vlan>-<id> ` .
931981
982+ ### ` apply-network-acl `
983+
984+ Apply Network ACL (Access Control List) rules for VPC networks.
985+
986+ ```
987+ network-namespace-wrapper.sh apply-network-acl \
988+ --network-id <id> \
989+ --vlan <vlan-id> \
990+ --acl-rules <base64-json> \
991+ [--vpc-id <vpc-id>]
992+ ```
993+
994+ The ` --acl-rules ` value is a Base64-encoded JSON array of ACL rule objects:
995+ ``` json
996+ [
997+ {
998+ "id" : 1 ,
999+ "number" : 100 ,
1000+ "trafficType" : " Ingress" ,
1001+ "action" : " Allow" ,
1002+ "protocol" : " tcp" ,
1003+ "portStart" : 80 ,
1004+ "portEnd" : 80 ,
1005+ "sourceCidrs" : [" 0.0.0.0/0" ]
1006+ },
1007+ {
1008+ "id" : 2 ,
1009+ "number" : 200 ,
1010+ "trafficType" : " Egress" ,
1011+ "action" : " Allow" ,
1012+ "protocol" : " all" ,
1013+ "destCidrs" : [" 0.0.0.0/0" ]
1014+ }
1015+ ]
1016+ ```
1017+
1018+ iptables design:
1019+
1020+ * ** Ingress rules** (filter FORWARD, chain ` CS_EXTNET_ACL_IN_<networkId> ` ):
1021+ Matches ` -i vn-<vlan>-<id> ` (traffic entering the VM namespace),
1022+ ordered by rule number. Actions: ACCEPT or DROP.
1023+
1024+ * ** Egress rules** (filter FORWARD, chain ` CS_EXTNET_ACL_OUT_<networkId> ` ):
1025+ Matches ` -o vn-<vlan>-<id> ` (traffic leaving the VM namespace),
1026+ ordered by rule number. Actions: ACCEPT or DROP.
1027+
1028+ Both chains are inserted at position 1 of ` CS_EXTNET_FWD_<networkId> ` so ACL rules
1029+ take precedence over the catch-all ACCEPT rules.
1030+
9321031### ` config-dhcp-subnet ` / ` remove-dhcp-subnet `
9331032
9341033Configure or tear down dnsmasq DHCP service for the network inside the namespace.
@@ -1226,6 +1325,23 @@ argument; hook scripts should parse the JSON argument as needed.
12261325
12271326## Developer / testing notes
12281327
1328+ ### VPC Support
1329+
1330+ The extension now supports ** VPC (Virtual Private Cloud)** networks in addition to
1331+ isolated networks. Key differences from isolated networks:
1332+
1333+ * ** Namespace sharing** : All tiers of a VPC share a single namespace (` cs-vpc-<vpcId> ` )
1334+ instead of each network getting its own (` cs-net-<networkId> ` ).
1335+ * ** Host affinity** : All tiers of a VPC land on the same KVM host via stable hash-based
1336+ selection using the VPC ID as the routing key.
1337+ * ** VPC-level operations** : ` implement-vpc ` , ` shutdown-vpc ` , ` destroy-vpc ` commands
1338+ manage VPC-wide state (namespace creation/teardown).
1339+ * ** VPC tier operations** : ` implement-network ` , ` shutdown-network ` , ` destroy-network `
1340+ commands manage per-tier bridges and routes; the namespace is preserved across
1341+ tier lifecycle operations.
1342+
1343+ ### Integration tests
1344+
12291345The integration smoke test at
12301346` test/integration/smoke/test_network_extension_namespace.py `
12311347exercises the full lifecycle against real KVM hosts in the zone.
@@ -1248,10 +1364,12 @@ The test covers:
12481364* Create / list / update / delete external network device.
12491365* Full network lifecycle: implement → assign-ip (source NAT) → static NAT →
12501366 port forwarding → firewall rules → DHCP/DNS → shutdown / destroy.
1367+ * VPC multi-tier networks with shared namespace and automatic host affinity.
12511368* NSP state transitions: Disabled → Enabled → Disabled → Deleted.
12521369* Tests ` test_04 ` , ` test_05 ` , ` test_06 ` (DHCP, DNS, LB) require ` arping ` ,
12531370 ` dnsmasq ` , and ` haproxy ` on the KVM hosts; the test skips them automatically
12541371 if these tools are not installed.
1372+ * Script cleanup on both management server and KVM hosts after each test.
12551373
12561374Run the test:
12571375``` bash
0 commit comments