Search in sources :

Example 1 with DtoRange

use of org.midonet.client.dto.DtoRule.DtoRange in project cloudstack by apache.

the class MidoNetElement method applyFWRules.

@Override
public boolean applyFWRules(Network config, List<? extends FirewallRule> rulesToApply) throws ResourceUnavailableException {
    if (!midoInNetwork(config)) {
        return false;
    }
    if (canHandle(config, Service.Firewall)) {
        String accountIdStr = getAccountUuid(config);
        String networkUUIDStr = String.valueOf(config.getId());
        RuleChain preFilter = getChain(accountIdStr, networkUUIDStr, RuleChainCode.TR_PREFILTER);
        RuleChain preNat = getChain(accountIdStr, networkUUIDStr, RuleChainCode.TR_PRENAT);
        // Create a map of Rule description -> Rule for quicker lookups
        Map<String, Rule> existingRules = new HashMap<String, Rule>();
        for (Rule existingRule : preFilter.getRules()) {
            // The "whitelist" rules we're interested in are the Jump rules where src address is specified
            if (existingRule.getType().equals(DtoRule.Jump) && existingRule.getNwSrcAddress() != null) {
                String ruleString = new SimpleFirewallRule(existingRule).toStringArray()[0];
                existingRules.put(ruleString, existingRule);
            }
        }
        for (FirewallRule rule : rulesToApply) {
            if (rule.getState() == FirewallRule.State.Revoke || rule.getState() == FirewallRule.State.Add) {
                IpAddress dstIp = _networkModel.getIp(rule.getSourceIpAddressId());
                FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, dstIp.getAddress().addr());
                // Convert to string representation
                SimpleFirewallRule fwRule = new SimpleFirewallRule(ruleTO);
                String[] ruleStrings = fwRule.toStringArray();
                if (rule.getState() == FirewallRule.State.Revoke) {
                    // Lookup in existingRules, delete if present
                    for (String revokeRuleString : ruleStrings) {
                        Rule foundRule = existingRules.get(revokeRuleString);
                        if (foundRule != null) {
                            foundRule.delete();
                        }
                    }
                } else if (rule.getState() == FirewallRule.State.Add) {
                    // Lookup in existingRules, add if not present
                    for (int i = 0; i < ruleStrings.length; i++) {
                        String ruleString = ruleStrings[i];
                        Rule foundRule = existingRules.get(ruleString);
                        if (foundRule == null) {
                            // Get the cidr for the related entry in the Source Cidrs list
                            String relatedCidr = fwRule.sourceCidrs.get(i);
                            Pair<String, Integer> cidrParts = NetUtils.getCidr(relatedCidr);
                            // Create rule with correct proto, cidr, ACCEPT, dst IP
                            Rule toApply = preFilter.addRule().type(DtoRule.Jump).jumpChainId(preNat.getId()).position(1).nwSrcAddress(cidrParts.first()).nwSrcLength(cidrParts.second()).nwDstAddress(ruleTO.getSrcIp()).nwDstLength(32).nwProto(SimpleFirewallRule.stringToProtocolNumber(rule.getProtocol()));
                            if (rule.getProtocol().equals("icmp")) {
                                // (-1, -1) means "allow all ICMP", so we don't set tpSrc / tpDst
                                if (fwRule.icmpType != -1 | fwRule.icmpCode != -1) {
                                    toApply.tpSrc(new DtoRange(fwRule.icmpType, fwRule.icmpType)).tpDst(new DtoRange(fwRule.icmpCode, fwRule.icmpCode));
                                }
                            } else {
                                toApply.tpDst(new DtoRange(fwRule.dstPortStart, fwRule.dstPortEnd));
                            }
                            toApply.create();
                        }
                    }
                }
            }
        }
        return true;
    } else {
        return true;
    }
}
Also used : DtoRange(org.midonet.client.dto.DtoRule.DtoRange) RuleChain(org.midonet.client.resource.RuleChain) HashMap(java.util.HashMap) IpAddress(com.cloud.network.IpAddress) PublicIpAddress(com.cloud.network.PublicIpAddress) Rule(org.midonet.client.resource.Rule) PortForwardingRule(com.cloud.network.rules.PortForwardingRule) FirewallRule(com.cloud.network.rules.FirewallRule) DtoRule(org.midonet.client.dto.DtoRule) FirewallRuleTO(com.cloud.agent.api.to.FirewallRuleTO) FirewallRule(com.cloud.network.rules.FirewallRule) Pair(com.cloud.utils.Pair)

Example 2 with DtoRange

use of org.midonet.client.dto.DtoRule.DtoRange in project cloudstack by apache.

the class MidoNetElement method applyPFRules.

@Override
public boolean applyPFRules(Network network, List<PortForwardingRule> rules) throws ResourceUnavailableException {
    s_logger.debug("applyPFRules called with network " + network.toString());
    if (!midoInNetwork(network)) {
        return false;
    }
    if (!canHandle(network, Service.PortForwarding)) {
        return false;
    }
    String accountIdStr = getAccountUuid(network);
    String networkUUIDStr = String.valueOf(network.getId());
    RuleChain preNat = getChain(accountIdStr, networkUUIDStr, RuleChainCode.TR_PRENAT);
    RuleChain postNat = getChain(accountIdStr, networkUUIDStr, RuleChainCode.TR_POST);
    RuleChain preFilter = getChain(accountIdStr, networkUUIDStr, RuleChainCode.TR_PREFILTER);
    Router providerRouter = api.getRouter(_providerRouterId);
    Router tenantRouter = getOrCreateGuestNetworkRouter(network);
    RouterPort[] ports = getOrCreateProviderRouterPorts(tenantRouter, providerRouter);
    RouterPort providerDownlink = ports[1];
    // Rules in the preNat table
    Map<String, Rule> existingPreNatRules = new HashMap<String, Rule>();
    for (Rule existingRule : preNat.getRules()) {
        // The "port forwarding" rules we're interested in are dnat rules where src / dst ports are specified
        if (existingRule.getType().equals(DtoRule.DNAT) && existingRule.getTpDst() != null) {
            String ruleString = new SimpleFirewallRule(existingRule).toStringArray()[0];
            existingPreNatRules.put(ruleString, existingRule);
        }
    }
    /*
         * Counts of rules associated with an IP address. Use this to check
         * how many rules we have of a given IP address. When it reaches 0,
         * we can delete the route associated with it.
         */
    Map<String, Integer> ipRuleCounts = new HashMap<String, Integer>();
    for (Rule rule : preNat.getRules()) {
        String ip = rule.getNwDstAddress();
        if (ip != null && rule.getNwDstLength() == 32) {
            if (ipRuleCounts.containsKey(ip)) {
                ipRuleCounts.put(ip, new Integer(ipRuleCounts.get(ip).intValue() + 1));
            } else {
                ipRuleCounts.put(ip, new Integer(1));
            }
        }
    }
    /*
         * Routes associated with IP. When we delete all the rules associated
         * with a given IP, we can delete the route associated with it.
         */
    Map<String, Route> routes = new HashMap<String, Route>();
    for (Route route : providerRouter.getRoutes(new MultivaluedMapImpl())) {
        String ip = route.getDstNetworkAddr();
        if (ip != null && route.getDstNetworkLength() == 32) {
            routes.put(ip, route);
        }
    }
    for (PortForwardingRule rule : rules) {
        IpAddress dstIp = _networkModel.getIp(rule.getSourceIpAddressId());
        PortForwardingRuleTO ruleTO = new PortForwardingRuleTO(rule, null, dstIp.getAddress().addr());
        SimpleFirewallRule fwRule = new SimpleFirewallRule(ruleTO);
        String[] ruleStrings = fwRule.toStringArray();
        if (rule.getState() == FirewallRule.State.Revoke) {
            /*
                 * Lookup in existingRules, delete if present
                 * We need to delete from both the preNat table and the
                 * postNat table.
                 */
            for (String revokeRuleString : ruleStrings) {
                Rule foundPreNatRule = existingPreNatRules.get(revokeRuleString);
                if (foundPreNatRule != null) {
                    String ip = foundPreNatRule.getNwDstAddress();
                    // is this the last rule associated with this IP?
                    Integer cnt = ipRuleCounts.get(ip);
                    if (cnt != null) {
                        if (cnt == 1) {
                            ipRuleCounts.remove(ip);
                            // no more rules for this IP. delete the route.
                            Route route = routes.remove(ip);
                            route.delete();
                        } else {
                            ipRuleCounts.put(ip, new Integer(ipRuleCounts.get(ip).intValue() - 1));
                        }
                    }
                    foundPreNatRule.delete();
                }
            }
        } else if (rule.getState() == FirewallRule.State.Add) {
            for (int i = 0; i < ruleStrings.length; i++) {
                String ruleString = ruleStrings[i];
                Rule foundRule = existingPreNatRules.get(ruleString);
                if (foundRule == null) {
                    String vmIp = ruleTO.getDstIp();
                    String publicIp = dstIp.getAddress().addr();
                    int privPortStart = ruleTO.getDstPortRange()[0];
                    int privPortEnd = ruleTO.getDstPortRange()[1];
                    int pubPortStart = ruleTO.getSrcPortRange()[0];
                    int pubPortEnd = ruleTO.getSrcPortRange()[1];
                    DtoRule.DtoNatTarget[] preTargets = new DtoRule.DtoNatTarget[] { new DtoRule.DtoNatTarget(vmIp, vmIp, privPortStart, privPortEnd) };
                    Rule preNatRule = preNat.addRule().type(DtoRule.DNAT).flowAction(DtoRule.Accept).nwDstAddress(publicIp).nwDstLength(32).tpDst(new DtoRange(pubPortStart, pubPortEnd)).natTargets(preTargets).nwProto(SimpleFirewallRule.stringToProtocolNumber(rule.getProtocol())).position(1);
                    Integer cnt = ipRuleCounts.get(publicIp);
                    if (cnt != null) {
                        ipRuleCounts.put(publicIp, new Integer(cnt.intValue() + 1));
                    } else {
                        ipRuleCounts.put(publicIp, new Integer(1));
                    }
                    String preNatRuleStr = new SimpleFirewallRule(preNatRule).toStringArray()[0];
                    existingPreNatRules.put(preNatRuleStr, preNatRule);
                    preNatRule.create();
                    if (routes.get(publicIp) == null) {
                        Route route = providerRouter.addRoute().type("Normal").weight(100).srcNetworkAddr("0.0.0.0").srcNetworkLength(0).dstNetworkAddr(publicIp).dstNetworkLength(32).nextHopPort(providerDownlink.getId());
                        route.create();
                        routes.put(publicIp, route);
                    }
                    // default firewall rule
                    if (canHandle(network, Service.Firewall)) {
                        boolean defaultBlock = false;
                        for (Rule filterRule : preFilter.getRules()) {
                            String pfDstIp = filterRule.getNwDstAddress();
                            if (pfDstIp != null && filterRule.getNwDstAddress().equals(publicIp)) {
                                defaultBlock = true;
                                break;
                            }
                        }
                        if (!defaultBlock) {
                            preFilter.addRule().type(DtoRule.Drop).nwDstAddress(publicIp).nwDstLength(32).create();
                        }
                    }
                }
            }
        }
    }
    return true;
}
Also used : DtoRange(org.midonet.client.dto.DtoRule.DtoRange) PortForwardingRuleTO(com.cloud.agent.api.to.PortForwardingRuleTO) HashMap(java.util.HashMap) DtoRule(org.midonet.client.dto.DtoRule) Router(org.midonet.client.resource.Router) MultivaluedMapImpl(com.sun.jersey.core.util.MultivaluedMapImpl) PortForwardingRule(com.cloud.network.rules.PortForwardingRule) RuleChain(org.midonet.client.resource.RuleChain) IpAddress(com.cloud.network.IpAddress) PublicIpAddress(com.cloud.network.PublicIpAddress) Rule(org.midonet.client.resource.Rule) PortForwardingRule(com.cloud.network.rules.PortForwardingRule) FirewallRule(com.cloud.network.rules.FirewallRule) DtoRule(org.midonet.client.dto.DtoRule) RouterPort(org.midonet.client.resource.RouterPort) Route(org.midonet.client.resource.Route)

Aggregations

IpAddress (com.cloud.network.IpAddress)2 PublicIpAddress (com.cloud.network.PublicIpAddress)2 FirewallRule (com.cloud.network.rules.FirewallRule)2 PortForwardingRule (com.cloud.network.rules.PortForwardingRule)2 HashMap (java.util.HashMap)2 DtoRule (org.midonet.client.dto.DtoRule)2 DtoRange (org.midonet.client.dto.DtoRule.DtoRange)2 Rule (org.midonet.client.resource.Rule)2 RuleChain (org.midonet.client.resource.RuleChain)2 FirewallRuleTO (com.cloud.agent.api.to.FirewallRuleTO)1 PortForwardingRuleTO (com.cloud.agent.api.to.PortForwardingRuleTO)1 Pair (com.cloud.utils.Pair)1 MultivaluedMapImpl (com.sun.jersey.core.util.MultivaluedMapImpl)1 Route (org.midonet.client.resource.Route)1 Router (org.midonet.client.resource.Router)1 RouterPort (org.midonet.client.resource.RouterPort)1