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;
}
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;
}
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;
}
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();
}
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;
}
Aggregations