Skip to content

Commit 8faf4a0

Browse files
committed
Allow port forwarding rules for the same public port but different CIDRs
1 parent c227c1d commit 8faf4a0

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
@@ -402,9 +402,10 @@ public void detectRulesConflict(FirewallRule newRule) throws NetworkRuleConflict
402402
((rule.getPurpose() == Purpose.Firewall || newRule.getPurpose() == Purpose.Firewall) && ((newRule.getPurpose() != rule.getPurpose()) || (!newRule.getProtocol()
403403
.equalsIgnoreCase(rule.getProtocol()))));
404404

405-
// if both rules are firewall and their cidrs are different, we can skip port ranges verification
406-
boolean bothRulesFirewall = (rule.getPurpose() == newRule.getPurpose() && rule.getPurpose() == Purpose.Firewall);
405+
// if both rules are firewall/port forwarding and their cidrs are different, we can skip port ranges verification
407406
boolean duplicatedCidrs = false;
407+
408+
boolean bothRulesFirewall = (rule.getPurpose() == newRule.getPurpose() && rule.getPurpose() == Purpose.Firewall);
408409
if (bothRulesFirewall) {
409410
_firewallDao.loadSourceCidrs(rule);
410411
_firewallDao.loadSourceCidrs((FirewallRuleVO)newRule);
@@ -418,6 +419,18 @@ public void detectRulesConflict(FirewallRule newRule) throws NetworkRuleConflict
418419
duplicatedCidrs = (detectConflictingCidrs(rule.getSourceCidrList(), newRule.getSourceCidrList()) && detectConflictingCidrs(rule.getDestinationCidrList(), newRule.getDestinationCidrList()));
419420
}
420421

422+
boolean bothRulesPortForwarding = rule.getPurpose() == newRule.getPurpose() && rule.getPurpose() == Purpose.PortForwarding;
423+
if (bothRulesPortForwarding) {
424+
_firewallDao.loadSourceCidrs(rule);
425+
_firewallDao.loadSourceCidrs((FirewallRuleVO) newRule);
426+
427+
if (rule.getSourceCidrList() == null || newRule.getSourceCidrList() == null) {
428+
continue;
429+
}
430+
431+
duplicatedCidrs = detectConflictingCidrs(rule.getSourceCidrList(), newRule.getSourceCidrList());
432+
}
433+
421434
if (!oneOfRulesIsFirewall) {
422435
if (rule.getPurpose() == Purpose.StaticNat && newRule.getPurpose() != Purpose.StaticNat) {
423436
throw new NetworkRuleConflictException("There is 1 to 1 Nat rule specified for the ip address id=" + newRule.getSourceIpAddressId());
@@ -452,7 +465,7 @@ public void detectRulesConflict(FirewallRule newRule) throws NetworkRuleConflict
452465
if (!notNullPorts) {
453466
continue;
454467
} else if (!oneOfRulesIsFirewall &&
455-
!(bothRulesFirewall && !duplicatedCidrs) &&
468+
!((bothRulesFirewall || bothRulesPortForwarding) && !duplicatedCidrs) &&
456469
((rule.getSourcePortStart().intValue() <= newRule.getSourcePortStart().intValue() &&
457470
rule.getSourcePortEnd().intValue() >= newRule.getSourcePortStart().intValue()) ||
458471
(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)