@Override
 @ActionEvent(
     eventType = EventTypes.EVENT_FIREWALL_OPEN,
     eventDescription = "creating firewall rule",
     create = true)
 public boolean addSystemFirewallRules(IPAddressVO ip, Account acct) {
   List<FirewallRuleVO> systemRules = _firewallDao.listSystemRules();
   for (FirewallRuleVO rule : systemRules) {
     try {
       if (rule.getSourceCidrList() == null
           && (rule.getPurpose() == Purpose.Firewall || rule.getPurpose() == Purpose.NetworkACL)) {
         _firewallDao.loadSourceCidrs(rule);
       }
       createFirewallRule(
           ip.getId(),
           acct,
           rule.getXid(),
           rule.getSourcePortStart(),
           rule.getSourcePortEnd(),
           rule.getProtocol(),
           rule.getSourceCidrList(),
           rule.getIcmpCode(),
           rule.getIcmpType(),
           rule.getRelated(),
           FirewallRuleType.System,
           rule.getNetworkId(),
           rule.getTrafficType());
     } catch (Exception e) {
       s_logger.debug("Failed to add system wide firewall rule, due to:" + e.toString());
     }
   }
   return true;
 }
  protected boolean revokeFirewallRule(long ruleId, boolean apply, Account caller, long userId) {

    FirewallRuleVO rule = _firewallDao.findById(ruleId);
    if (rule == null || rule.getPurpose() != Purpose.Firewall) {
      throw new InvalidParameterValueException(
          "Unable to find " + ruleId + " having purpose " + Purpose.Firewall);
    }

    if (rule.getType() == FirewallRuleType.System
        && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
      throw new InvalidParameterValueException(
          "Only root admin can delete the system wide firewall rule");
    }

    _accountMgr.checkAccess(caller, null, true, rule);

    revokeRule(rule, caller, userId, false);

    boolean success = false;
    Long networkId = rule.getNetworkId();

    if (apply) {
      // ingress firewall rule
      if (rule.getSourceIpAddressId() != null) {
        // feteches ingress firewall, ingress firewall rules associated with the ip
        List<FirewallRuleVO> rules =
            _firewallDao.listByIpAndPurpose(rule.getSourceIpAddressId(), Purpose.Firewall);
        return applyFirewallRules(rules, false, caller);
        // egress firewall rule
      } else if (networkId != null) {
        List<FirewallRuleVO> rules =
            _firewallDao.listByNetworkPurposeTrafficType(
                rule.getNetworkId(), Purpose.Firewall, FirewallRule.TrafficType.Egress);
        return applyFirewallRules(rules, false, caller);
      }
    } else {
      success = true;
    }

    return success;
  }
  @Override
  public void detectRulesConflict(FirewallRule newRule) throws NetworkRuleConflictException {
    List<FirewallRuleVO> rules;
    if (newRule.getSourceIpAddressId() != null) {
      rules = _firewallDao.listByIpAndPurposeAndNotRevoked(newRule.getSourceIpAddressId(), null);
      assert (rules.size() >= 1)
          : "For network rules, we now always first persist the rule and then check for "
              + "network conflicts so we should at least have one rule at this point.";
    } else {
      // fetches only firewall egress rules.
      rules =
          _firewallDao.listByNetworkPurposeTrafficTypeAndNotRevoked(
              newRule.getNetworkId(), Purpose.Firewall, newRule.getTrafficType());
      assert (rules.size() >= 1);
    }

    for (FirewallRuleVO rule : rules) {
      if (rule.getId() == newRule.getId()) {
        continue; // Skips my own rule.
      }

      boolean oneOfRulesIsFirewall =
          ((rule.getPurpose() == Purpose.Firewall || newRule.getPurpose() == Purpose.Firewall)
              && ((newRule.getPurpose() != rule.getPurpose())
                  || (!newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()))));

      // if both rules are firewall and their cidrs are different, we can skip port ranges
      // verification
      boolean bothRulesFirewall =
          (rule.getPurpose() == newRule.getPurpose() && rule.getPurpose() == Purpose.Firewall);
      boolean duplicatedCidrs = false;
      if (bothRulesFirewall) {
        // Verify that the rules have different cidrs
        _firewallDao.loadSourceCidrs(rule);
        _firewallDao.loadSourceCidrs((FirewallRuleVO) newRule);

        List<String> ruleCidrList = rule.getSourceCidrList();
        List<String> newRuleCidrList = newRule.getSourceCidrList();

        if (ruleCidrList == null || newRuleCidrList == null) {
          continue;
        }

        Collection<String> similar = new HashSet<String>(ruleCidrList);
        similar.retainAll(newRuleCidrList);

        if (similar.size() > 0) {
          duplicatedCidrs = true;
        }
      }

      if (!oneOfRulesIsFirewall) {
        if (rule.getPurpose() == Purpose.StaticNat && newRule.getPurpose() != Purpose.StaticNat) {
          throw new NetworkRuleConflictException(
              "There is 1 to 1 Nat rule specified for the ip address id="
                  + newRule.getSourceIpAddressId());
        } else if (rule.getPurpose() != Purpose.StaticNat
            && newRule.getPurpose() == Purpose.StaticNat) {
          throw new NetworkRuleConflictException(
              "There is already firewall rule specified for the ip address id="
                  + newRule.getSourceIpAddressId());
        }
      }

      if (rule.getNetworkId() != newRule.getNetworkId() && rule.getState() != State.Revoke) {
        throw new NetworkRuleConflictException(
            "New rule is for a different network than what's specified in rule " + rule.getXid());
      }

      if (newRule.getProtocol().equalsIgnoreCase(NetUtils.ICMP_PROTO)
          && newRule.getProtocol().equalsIgnoreCase(rule.getProtocol())) {
        if (newRule.getIcmpCode().longValue() == rule.getIcmpCode().longValue()
            && newRule.getIcmpType().longValue() == rule.getIcmpType().longValue()
            && newRule.getProtocol().equalsIgnoreCase(rule.getProtocol())
            && duplicatedCidrs) {
          throw new InvalidParameterValueException(
              "New rule conflicts with existing rule id=" + rule.getId());
        }
      }

      boolean notNullPorts =
          (newRule.getSourcePortStart() != null
              && newRule.getSourcePortEnd() != null
              && rule.getSourcePortStart() != null
              && rule.getSourcePortEnd() != null);
      if (!notNullPorts) {
        continue;
      } else if (!oneOfRulesIsFirewall
          && !(bothRulesFirewall && !duplicatedCidrs)
          && ((rule.getSourcePortStart().intValue() <= newRule.getSourcePortStart().intValue()
                  && rule.getSourcePortEnd().intValue() >= newRule.getSourcePortStart().intValue())
              || (rule.getSourcePortStart().intValue() <= newRule.getSourcePortEnd().intValue()
                  && rule.getSourcePortEnd().intValue() >= newRule.getSourcePortEnd().intValue())
              || (newRule.getSourcePortStart().intValue() <= rule.getSourcePortStart().intValue()
                  && newRule.getSourcePortEnd().intValue() >= rule.getSourcePortStart().intValue())
              || (newRule.getSourcePortStart().intValue() <= rule.getSourcePortEnd().intValue()
                  && newRule.getSourcePortEnd().intValue()
                      >= rule.getSourcePortEnd().intValue()))) {

        // we allow port forwarding rules with the same parameters but different protocols
        boolean allowPf =
            (rule.getPurpose() == Purpose.PortForwarding
                && newRule.getPurpose() == Purpose.PortForwarding
                && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()));
        boolean allowStaticNat =
            (rule.getPurpose() == Purpose.StaticNat
                && newRule.getPurpose() == Purpose.StaticNat
                && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()));

        if (!(allowPf || allowStaticNat || oneOfRulesIsFirewall)) {
          throw new NetworkRuleConflictException(
              "The range specified, "
                  + newRule.getSourcePortStart()
                  + "-"
                  + newRule.getSourcePortEnd()
                  + ", conflicts with rule "
                  + rule.getId()
                  + " which has "
                  + rule.getSourcePortStart()
                  + "-"
                  + rule.getSourcePortEnd());
        }
      }
    }

    if (s_logger.isDebugEnabled()) {
      s_logger.debug(
          "No network rule conflicts detected for "
              + newRule
              + " against "
              + (rules.size() - 1)
              + " existing rules");
    }
  }