Skip to content

Commit 3a75572

Browse files
committed
Allow port forwarding rules for the same public port but different CIDRs
1 parent 7bb2713 commit 3a75572

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

server/src/main/java/com/cloud/network/firewall/FirewallManagerImpl.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -391,9 +391,10 @@ public void detectRulesConflict(FirewallRule newRule) throws NetworkRuleConflict
391391
((rule.getPurpose() == Purpose.Firewall || newRule.getPurpose() == Purpose.Firewall) && ((newRule.getPurpose() != rule.getPurpose()) || (!newRule.getProtocol()
392392
.equalsIgnoreCase(rule.getProtocol()))));
393393

394-
// if both rules are firewall and their cidrs are different, we can skip port ranges verification
395-
boolean bothRulesFirewall = (rule.getPurpose() == newRule.getPurpose() && rule.getPurpose() == Purpose.Firewall);
394+
// if both rules are firewall/port forwarding and their cidrs are different, we can skip port ranges verification
396395
boolean duplicatedCidrs = false;
396+
397+
boolean bothRulesFirewall = (rule.getPurpose() == newRule.getPurpose() && rule.getPurpose() == Purpose.Firewall);
397398
if (bothRulesFirewall) {
398399
_firewallDao.loadSourceCidrs(rule);
399400
_firewallDao.loadSourceCidrs((FirewallRuleVO)newRule);
@@ -407,6 +408,18 @@ public void detectRulesConflict(FirewallRule newRule) throws NetworkRuleConflict
407408
duplicatedCidrs = (detectConflictingCidrs(rule.getSourceCidrList(), newRule.getSourceCidrList()) && detectConflictingCidrs(rule.getDestinationCidrList(), newRule.getDestinationCidrList()));
408409
}
409410

411+
boolean bothRulesPortForwarding = rule.getPurpose() == newRule.getPurpose() && rule.getPurpose() == Purpose.PortForwarding;
412+
if (bothRulesPortForwarding) {
413+
_firewallDao.loadSourceCidrs(rule);
414+
_firewallDao.loadSourceCidrs((FirewallRuleVO) newRule);
415+
416+
if (rule.getSourceCidrList() == null || newRule.getSourceCidrList() == null) {
417+
continue;
418+
}
419+
420+
duplicatedCidrs = detectConflictingCidrs(rule.getSourceCidrList(), newRule.getSourceCidrList());
421+
}
422+
410423
if (!oneOfRulesIsFirewall) {
411424
if (rule.getPurpose() == Purpose.StaticNat && newRule.getPurpose() != Purpose.StaticNat) {
412425
throw new NetworkRuleConflictException("There is 1 to 1 Nat rule specified for the ip address id=" + newRule.getSourceIpAddressId());
@@ -441,7 +454,7 @@ public void detectRulesConflict(FirewallRule newRule) throws NetworkRuleConflict
441454
if (!notNullPorts) {
442455
continue;
443456
} else if (!oneOfRulesIsFirewall &&
444-
!(bothRulesFirewall && !duplicatedCidrs) &&
457+
!((bothRulesFirewall || bothRulesPortForwarding) && !duplicatedCidrs) &&
445458
((rule.getSourcePortStart().intValue() <= newRule.getSourcePortStart().intValue() &&
446459
rule.getSourcePortEnd().intValue() >= newRule.getSourcePortStart().intValue()) ||
447460
(rule.getSourcePortStart().intValue() <= newRule.getSourcePortEnd().intValue() &&

systemvm/debian/opt/cloud/bin/cs_forwardingrules.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,18 @@ def ruleCompare(ruleA, ruleB):
7878
return ruleA["public_ip"] == ruleB["public_ip"]
7979
elif ruleA["type"] == "forward":
8080
return ruleA["public_ip"] == ruleB["public_ip"] and ruleA["public_ports"] == ruleB["public_ports"] \
81-
and ruleA["protocol"] == ruleB["protocol"]
81+
and ruleA["protocol"] == ruleB["protocol"] and cidrsConflict(ruleA.get("source_cidr_list"), ruleB.get("source_cidr_list"))
82+
83+
# Same validation as in com.cloud.network.firewall.FirewallManagerImpl.detectConflictingCidrs
84+
def cidrsConflict(cidrListA, cidrListB):
85+
if not cidrListA and not cidrListB:
86+
return True
87+
if not cidrListA:
88+
return False
89+
if not cidrListB:
90+
return False
91+
92+
cidrListA = set(cidrListA.split(","))
93+
cidrListB = set(cidrListB.split(","))
94+
95+
return len(cidrListA.intersection(cidrListB)) > 0

0 commit comments

Comments
 (0)