1818
1919import java .io .File ;
2020import java .net .URI ;
21- import java .net .InetAddress ;
22- import java .nio .ByteBuffer ;
2321import java .nio .file .Files ;
2422import java .util .ArrayList ;
2523import java .util .HashMap ;
9896import com .cloud .utils .Pair ;
9997import com .cloud .utils .component .AdapterBase ;
10098import com .cloud .utils .exception .CloudRuntimeException ;
99+ import com .cloud .utils .net .NetUtils ;
101100import com .cloud .vm .Nic ;
102101import com .cloud .vm .NicProfile ;
103102import com .cloud .vm .NicVO ;
@@ -714,29 +713,9 @@ public boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddre
714713 boolean isRevoke = ip .getState () == IpAddress .State .Releasing ;
715714 String action = isRevoke ? CMD_RELEASE_IP : CMD_ASSIGN_IP ;
716715
717- // Public VLAN tag (e.g. "101") from the IP's VLAN record.
718- String publicVlanTag = safeStr (ip .getVlanTag ());
719-
720- // Compute public IP gateway and CIDR (from the PublicIpAddress if available)
721- String publicGateway ;
722- String publicCidr ;
723- try {
724- publicGateway = ip .getGateway ();
725- String publicIpStr = ip .getAddress () != null ? ip .getAddress ().addr () : null ;
726- String publicNetmask = ip .getNetmask ();
727- publicCidr = buildCidrFromIpAndNetmask (publicIpStr , publicNetmask );
728- } catch (Exception e ) {
729- publicGateway = null ;
730- publicCidr = null ;
731- }
732-
733716 JsonObject payload = new JsonObject ();
734717 addNetworkToPayload (payload , network );
735- payload .addProperty ("public_ip" , ip .getAddress ().addr ());
736- payload .addProperty ("source_nat" , String .valueOf (isSourceNat ));
737- payload .addProperty ("public_gateway" , safeStr (publicGateway ));
738- payload .addProperty ("public_cidr" , safeStr (publicCidr ));
739- payload .addProperty ("public_vlan" , publicVlanTag );
718+ addPublicIpToPayload (payload , ip .getId (), isSourceNat );
740719
741720 boolean result = executeScript (network , action , payload );
742721 if (!result ) {
@@ -748,31 +727,6 @@ public boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddre
748727 return true ;
749728 }
750729
751- /**
752- * Build a CIDR string from IP address and dotted netmask (or prefix).
753- * Returns "" if either value is null or parsing fails.
754- */
755- private String buildCidrFromIpAndNetmask (String ipStr , String netmaskStr ) {
756- if (StringUtils .isEmpty (ipStr ) || StringUtils .isEmpty (netmaskStr )) {
757- return "" ;
758- }
759- // If netmask is already CIDR (contains '/'), try to return network/prefix
760- if (netmaskStr .contains ("/" )) {
761- return netmaskStr ;
762- }
763- try {
764- InetAddress ip = InetAddress .getByName (ipStr );
765- InetAddress mask = InetAddress .getByName (netmaskStr );
766- int maskInt = ByteBuffer .wrap (mask .getAddress ()).getInt ();
767- int prefix = Integer .bitCount (maskInt );
768- // Return the provided IP with the calculated prefix so the address retains its host value
769- return ip .getHostAddress () + "/" + prefix ;
770- } catch (Exception e ) {
771- logger .debug ("Failed to compute CIDR from ip/netmask {} {}: {}" , ipStr , netmaskStr , e .getMessage ());
772- return "" ;
773- }
774- }
775-
776730 // ---- StaticNatServiceProvider ----
777731
778732 @ Override
@@ -787,14 +741,9 @@ public boolean applyStaticNats(Network config, List<? extends StaticNat> rules)
787741 logger .info ("Applying {} static NAT rules for network {}" , rules .size (), config );
788742 for (StaticNat rule : rules ) {
789743 String action = rule .isForRevoke () ? CMD_DELETE_STATIC_NAT : CMD_ADD_STATIC_NAT ;
790- String publicCidr = getPublicCidr (rule .getSourceIpAddressId ());
791- String publicVlanTag = getPublicVlanTag (rule .getSourceIpAddressId ());
792-
793744 JsonObject payload = new JsonObject ();
794745 addNetworkToPayload (payload , config );
795- payload .addProperty ("public_ip" , getIpAddress (rule .getSourceIpAddressId ()));
796- payload .addProperty ("public_cidr" , safeStr (publicCidr ));
797- payload .addProperty ("public_vlan" , publicVlanTag );
746+ addPublicIpToPayload (payload , rule .getSourceIpAddressId (), false );
798747 payload .addProperty ("private_ip" , safeStr (rule .getDestIpAddress ()));
799748 boolean result = executeScript (config , action , payload );
800749 if (!result ) {
@@ -822,14 +771,9 @@ public boolean applyPFRules(Network network, List<PortForwardingRule> rules)
822771 String action = isRevoke ? CMD_DELETE_PORT_FORWARD : CMD_ADD_PORT_FORWARD ;
823772 String publicPort = PortForwardingServiceProvider .getPublicPortRange (rule );
824773 String privatePort = PortForwardingServiceProvider .getPrivatePFPortRange (rule );
825- String publicCidr = getPublicCidr (rule .getSourceIpAddressId ());
826- String publicVlanTag = getPublicVlanTag (rule .getSourceIpAddressId ());
827-
828774 JsonObject payload = new JsonObject ();
829775 addNetworkToPayload (payload , network );
830- payload .addProperty ("public_ip" , getIpAddress (rule .getSourceIpAddressId ()));
831- payload .addProperty ("public_cidr" , safeStr (publicCidr ));
832- payload .addProperty ("public_vlan" , publicVlanTag );
776+ addPublicIpToPayload (payload , rule .getSourceIpAddressId (), false );
833777 payload .addProperty ("public_port" , safeStr (publicPort ));
834778 payload .addProperty ("private_ip" , safeStr (rule .getDestinationIpAddress () != null
835779 ? rule .getDestinationIpAddress ().addr () : null ));
@@ -1384,28 +1328,29 @@ private String getIpAddress(Long ipAddressId) {
13841328 return ip != null ? ip .getAddress ().addr () : "" ;
13851329 }
13861330
1387- private String getPublicCidr (Long ipAddressId ) {
1388- if (ipAddressId == null ) {
1389- return "" ;
1390- }
1391- IpAddress ip = networkModel .getIp (ipAddressId );
1392- if (ip .getAddress () == null ) {
1393- return "" ;
1394- }
1395- VlanVO vlan = vlanDao .findById (ip .getVlanId ());
1396- return buildCidrFromIpAndNetmask (ip .getAddress ().addr (), vlan .getVlanNetmask ());
1397- }
1398-
1399- private String getPublicVlanTag (Long ipAddressId ) {
1400- if (ipAddressId == null ) {
1401- return "" ;
1331+ /**
1332+ * Adds all standard public-IP fields to the payload.
1333+ * Makes exactly two DB calls: one for the {@link IpAddress} and one for
1334+ * its {@link VlanVO}. All five fields are then derived from those two
1335+ * objects in memory — no further DB calls are made.
1336+ * Fields: {@code public_ip}, {@code public_vlan}, {@code public_gateway},
1337+ * {@code public_cidr}, {@code source_nat}.
1338+ */
1339+ private void addPublicIpToPayload (JsonObject payload , Long ipAddressId , boolean sourceNat ) {
1340+ if (payload == null || ipAddressId == null ) {
1341+ return ;
14021342 }
14031343 IpAddress ip = networkModel .getIp (ipAddressId );
1404- if (ip == null ) {
1405- return "" ;
1344+ if (ip == null || ip . getAddress () == null ) {
1345+ return ;
14061346 }
14071347 VlanVO vlan = vlanDao .findById (ip .getVlanId ());
1408- return vlan != null ? safeStr (vlan .getVlanTag ()) : "" ;
1348+ payload .addProperty ("public_ip" , safeStr (ip .getAddress ().addr ()));
1349+ payload .addProperty ("public_vlan" , vlan != null ? safeStr (vlan .getVlanTag ()) : "" );
1350+ payload .addProperty ("public_gateway" , vlan != null ? safeStr (vlan .getVlanGateway ()) : "" );
1351+ payload .addProperty ("public_cidr" , vlan != null
1352+ ? StringUtils .defaultString (NetUtils .ipAndNetMaskToCidr (ip .getAddress ().addr (), vlan .getVlanNetmask ())) : "" );
1353+ payload .addProperty ("source_nat" , String .valueOf (sourceNat ));
14091354 }
14101355
14111356 private String safeStr (String value ) {
@@ -2384,11 +2329,7 @@ public boolean implementVpc(Vpc vpc, DeployDestination dest, ReservationContext
23842329 // VPC-level SNAT rule for the entire VPC CIDR.
23852330 final PublicIpAddress sourceNatIp = getVpcSourceNatIp (vpc .getId ());
23862331 if (sourceNatIp != null ) {
2387- implPayload .addProperty ("public_ip" , safeStr (sourceNatIp .getAddress ().addr ()));
2388- implPayload .addProperty ("public_vlan" , safeStr (getPublicVlanTag (sourceNatIp .getId ())));
2389- implPayload .addProperty ("public_gateway" , safeStr (sourceNatIp .getGateway ()));
2390- implPayload .addProperty ("public_cidr" , safeStr (getPublicCidr (sourceNatIp .getId ())));
2391- implPayload .addProperty ("source_nat" , "true" );
2332+ addPublicIpToPayload (implPayload , sourceNatIp .getId (), true );
23922333 }
23932334
23942335 return executeVpcScript (vpc , CMD_IMPLEMENT_VPC , implPayload );
@@ -2474,14 +2415,9 @@ public boolean updateVpcSourceNatIp(Vpc vpc, IpAddress address) {
24742415 }
24752416
24762417 final JsonObject payload = new JsonObject ();
2477- final VlanVO vlan = vlanDao .findById (address .getVlanId ());
24782418 payload .addProperty ("vpc_id" , String .valueOf (vpc .getId ()));
24792419 payload .addProperty ("cidr" , safeStr (vpc .getCidr ()));
2480- payload .addProperty ("public_ip" , safeStr (address .getAddress ().addr ()));
2481- payload .addProperty ("public_vlan" , safeStr (getPublicVlanTag (address .getId ())));
2482- payload .addProperty ("public_gateway" , vlan != null ? safeStr (vlan .getVlanGateway ()) : "" );
2483- payload .addProperty ("public_cidr" , safeStr (getPublicCidr (address .getId ())));
2484- payload .addProperty ("source_nat" , "true" );
2420+ addPublicIpToPayload (payload , address .getId (), true );
24852421
24862422 final boolean result = executeVpcScript (vpc , CMD_UPDATE_VPC_SOURCE_NAT_IP , payload );
24872423 if (!result ) {
0 commit comments