Search in sources :

Example 6 with RouterPort

use of org.midonet.client.resource.RouterPort in project cloudstack by apache.

the class MidoNetElement method getOrCreatePublicBridgePorts.

private Port[] getOrCreatePublicBridgePorts(NicProfile nic, Bridge publicBridge, Router providerRouter) {
    Port[] ports = new Port[2];
    BridgePort bridgeUplink = null;
    RouterPort providerDownlink = null;
    // Check if the ports and connection already exist
    for (Port peerPort : publicBridge.getPeerPorts()) {
        if (peerPort != null && peerPort instanceof RouterPort) {
            RouterPort checkPort = (RouterPort) peerPort;
            // Check it's a port on the providerRouter with the right gateway address
            if (checkPort.getDeviceId().compareTo(providerRouter.getId()) == 0 && checkPort.getPortAddress().equals(nic.getIPv4Gateway())) {
                providerDownlink = checkPort;
                bridgeUplink = (BridgePort) api.getPort(checkPort.getPeerId());
                break;
            }
        }
    }
    // Create the ports and connection if they don't exist
    if (providerDownlink == null) {
        String cidr = NetUtils.ipAndNetMaskToCidr(nic.getIPv4Gateway(), nic.getIPv4Netmask());
        String cidrSubnet = NetUtils.getCidrSubNet(cidr);
        int cidrSize = (int) NetUtils.getCidrSize(NetUtils.cidr2Netmask(cidr));
        String gateway = nic.getIPv4Gateway();
        // Add interior port on router side, with network details
        providerDownlink = providerRouter.addInteriorRouterPort().networkAddress(cidrSubnet).networkLength(cidrSize).portAddress(gateway).create();
        bridgeUplink = publicBridge.addInteriorPort().create();
        // Link them up
        providerDownlink.link(bridgeUplink.getId()).update();
    }
    ports[0] = bridgeUplink;
    ports[1] = providerDownlink;
    return ports;
}
Also used : BridgePort(org.midonet.client.resource.BridgePort) RouterPort(org.midonet.client.resource.RouterPort) BridgePort(org.midonet.client.resource.BridgePort) Port(org.midonet.client.resource.Port) RouterPort(org.midonet.client.resource.RouterPort)

Example 7 with RouterPort

use of org.midonet.client.resource.RouterPort 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)

Example 8 with RouterPort

use of org.midonet.client.resource.RouterPort in project cloudstack by apache.

the class MidoNetElement method associatePublicIP.

public boolean associatePublicIP(Network network, final List<? extends PublicIpAddress> ipAddress) throws ResourceUnavailableException {
    s_logger.debug("associatePublicIP called with network: " + network.toString());
    /*
         * Get Mido Router for this network and set source rules
         * These should only be allocated inside the for loop, because
         * this function could be called as a part of network cleanup. In
         * that case, we do not want to recreate the guest network or
         * any ports.
         */
    boolean resources = false;
    Router tenantRouter = null;
    Router providerRouter = null;
    RouterPort[] ports = null;
    RouterPort tenantUplink = null;
    RouterPort providerDownlink = null;
    RuleChain preNat = null;
    RuleChain post = null;
    String accountIdStr = null;
    String routerName = null;
    // Set Source NAT rules on router
    for (PublicIpAddress ip : ipAddress) {
        // ip is the external one we sourcenat to
        if (ip.isSourceNat()) {
            if (resources == false) {
                tenantRouter = getOrCreateGuestNetworkRouter(network);
                providerRouter = api.getRouter(_providerRouterId);
                ports = getOrCreateProviderRouterPorts(tenantRouter, providerRouter);
                tenantUplink = ports[0];
                providerDownlink = ports[1];
                accountIdStr = getAccountUuid(network);
                boolean isVpc = getIsVpc(network);
                long id = getRouterId(network, isVpc);
                routerName = getRouterName(isVpc, id);
                preNat = getChain(accountIdStr, routerName, RuleChainCode.TR_PRENAT);
                post = api.getChain(tenantRouter.getOutboundFilterId());
                resources = true;
            }
            applySourceNat(// Routers
            tenantRouter, // Routers
            providerRouter, // Ports
            tenantUplink, // Ports
            providerDownlink, // Chains
            preNat, // Chains
            post, // The IP
            ip);
        }
    }
    return true;
}
Also used : PublicIpAddress(com.cloud.network.PublicIpAddress) RuleChain(org.midonet.client.resource.RuleChain) Router(org.midonet.client.resource.Router) RouterPort(org.midonet.client.resource.RouterPort)

Example 9 with RouterPort

use of org.midonet.client.resource.RouterPort in project cloudstack by apache.

the class MidoNetElement method connectBridgeToRouter.

private void connectBridgeToRouter(Network network, Bridge netBridge, Router netRouter) {
    boolean isVpc = getIsVpc(network);
    long id = getRouterId(network, isVpc);
    String routerName = getRouterName(isVpc, id);
    String accountIdStr = getAccountUuid(network);
    // Add interior port on bridge side
    BridgePort bridgePort = netBridge.addInteriorPort().create();
    // Add interior port on router side, with network details
    RouterPort routerPort = netRouter.addInteriorRouterPort();
    String cidr = network.getCidr();
    String cidrSubnet = NetUtils.getCidrSubNet(cidr);
    int cidrSize = (int) NetUtils.getCidrSize(NetUtils.cidr2Netmask(cidr));
    routerPort.networkAddress(cidrSubnet);
    routerPort.networkLength(cidrSize);
    routerPort.portAddress(network.getGateway());
    // implemented via chains on the router port to that network.
    if (getIsVpc(network)) {
        // Create ACL filter chain for traffic coming INTO the network
        // (outbound from the port
        int pos = 1;
        RuleChain inc = api.addChain().name(getChainName(String.valueOf(network.getId()), routerName, RuleChainCode.ACL_INGRESS)).tenantId(accountIdStr).create();
        // If it is ARP, accept it
        inc.addRule().type(DtoRule.Accept).dlType(0x0806).position(pos++).create();
        // If it is ICMP to the router, accept that
        inc.addRule().type(DtoRule.Accept).nwProto(SimpleFirewallRule.stringToProtocolNumber("icmp")).nwDstAddress(network.getGateway()).nwDstLength(32).position(pos++).create();
        // If it is connection tracked, accept that as well
        inc.addRule().type(DtoRule.Accept).matchReturnFlow(true).position(pos++).create();
        inc.addRule().type(DtoRule.Drop).position(pos).create();
        //
        RuleChain out = api.addChain().name(getChainName(String.valueOf(network.getId()), routerName, RuleChainCode.ACL_EGRESS)).tenantId(accountIdStr).create();
        // Creating the first default rule here that does nothing
        // but start connection tracking.
        out.addRule().type(DtoRule.Accept).matchForwardFlow(true).position(1).create();
        routerPort.outboundFilterId(inc.getId());
        routerPort.inboundFilterId(out.getId());
    }
    routerPort.create();
    // Link them up
    bridgePort.link(routerPort.getId()).update();
    // Set up default route from router to subnet
    netRouter.addRoute().type("Normal").weight(100).srcNetworkAddr("0.0.0.0").srcNetworkLength(0).dstNetworkAddr(cidrSubnet).dstNetworkLength(cidrSize).nextHopPort(routerPort.getId()).nextHopGateway(null).create();
}
Also used : BridgePort(org.midonet.client.resource.BridgePort) RuleChain(org.midonet.client.resource.RuleChain) RouterPort(org.midonet.client.resource.RouterPort)

Example 10 with RouterPort

use of org.midonet.client.resource.RouterPort in project cloudstack by apache.

the class MidoNetElement method getOrCreateProviderRouterPorts.

protected RouterPort[] getOrCreateProviderRouterPorts(Router tenantRouter, Router providerRouter) {
    RouterPort[] ports = new RouterPort[2];
    RouterPort tenantUplink = null;
    RouterPort providerDownlink = null;
    // Check if the ports and connection already exist
    for (Port peerPort : tenantRouter.getPeerPorts((new MultivaluedMapImpl()))) {
        if (peerPort != null && peerPort instanceof RouterPort) {
            RouterPort checkPort = (RouterPort) peerPort;
            if (checkPort.getDeviceId().compareTo(providerRouter.getId()) == 0) {
                providerDownlink = checkPort;
                tenantUplink = (RouterPort) api.getPort(checkPort.getPeerId());
                break;
            }
        }
    }
    // Create the ports and connection if they don't exist
    if (providerDownlink == null) {
        // Add interior port on router side, with network details
        providerDownlink = providerRouter.addInteriorRouterPort().networkAddress("169.254.255.0").networkLength(32).portAddress("169.254.255.1").create();
        tenantUplink = tenantRouter.addInteriorRouterPort().networkAddress("169.254.255.0").networkLength(32).portAddress("169.254.255.2").create();
        // Link them up
        providerDownlink.link(tenantUplink.getId()).update();
    }
    ports[0] = tenantUplink;
    ports[1] = providerDownlink;
    return ports;
}
Also used : RouterPort(org.midonet.client.resource.RouterPort) BridgePort(org.midonet.client.resource.BridgePort) Port(org.midonet.client.resource.Port) MultivaluedMapImpl(com.sun.jersey.core.util.MultivaluedMapImpl) RouterPort(org.midonet.client.resource.RouterPort)

Aggregations

RouterPort (org.midonet.client.resource.RouterPort)10 BridgePort (org.midonet.client.resource.BridgePort)7 Port (org.midonet.client.resource.Port)6 Router (org.midonet.client.resource.Router)6 RuleChain (org.midonet.client.resource.RuleChain)5 MultivaluedMapImpl (com.sun.jersey.core.util.MultivaluedMapImpl)4 PublicIpAddress (com.cloud.network.PublicIpAddress)3 Route (org.midonet.client.resource.Route)3 IpAddress (com.cloud.network.IpAddress)2 UUID (java.util.UUID)2 Bridge (org.midonet.client.resource.Bridge)2 PortForwardingRuleTO (com.cloud.agent.api.to.PortForwardingRuleTO)1 ConcurrentOperationException (com.cloud.exception.ConcurrentOperationException)1 InsufficientCapacityException (com.cloud.exception.InsufficientCapacityException)1 ResourceUnavailableException (com.cloud.exception.ResourceUnavailableException)1 Network (com.cloud.network.Network)1 FirewallRule (com.cloud.network.rules.FirewallRule)1 PortForwardingRule (com.cloud.network.rules.PortForwardingRule)1 StaticNat (com.cloud.network.rules.StaticNat)1 AccountVO (com.cloud.user.AccountVO)1