Merge branch '4.9'

This commit is contained in:
Rohit Yadav 2016-12-08 00:04:26 +05:30
commit 6bdc411ff2
No known key found for this signature in database
GPG Key ID: 484248210EE3D884
10 changed files with 1432 additions and 40 deletions

View File

@ -41,7 +41,7 @@ public class IpAssociationConfigItem extends AbstractConfigItemFacade {
for (final IpAddressTO ip : command.getIpAddresses()) { for (final IpAddressTO ip : command.getIpAddresses()) {
final IpAddress ipAddress = new IpAddress(ip.getPublicIp(), ip.isSourceNat(), ip.isAdd(), ip.isOneToOneNat(), ip.isFirstIP(), ip.getVlanGateway(), ip.getVlanNetmask(), final IpAddress ipAddress = new IpAddress(ip.getPublicIp(), ip.isSourceNat(), ip.isAdd(), ip.isOneToOneNat(), ip.isFirstIP(), ip.getVlanGateway(), ip.getVlanNetmask(),
ip.getVifMacAddress(), ip.getNicDevId(), ip.isNewNic()); ip.getVifMacAddress(), ip.getNicDevId(), ip.isNewNic(), ip.getTrafficType().toString());
ips.add(ipAddress); ips.add(ipAddress);
} }

View File

@ -31,13 +31,14 @@ public class IpAddress {
private String vifMacAddress; private String vifMacAddress;
private Integer nicDevId; private Integer nicDevId;
private boolean newNic; private boolean newNic;
private String nwType;
public IpAddress() { public IpAddress() {
// Empty constructor for (de)serialization // Empty constructor for (de)serialization
} }
public IpAddress(String publicIp, boolean sourceNat, boolean add, boolean oneToOneNat, boolean firstIP, String gateway, String netmask, String vifMacAddress, public IpAddress(String publicIp, boolean sourceNat, boolean add, boolean oneToOneNat, boolean firstIP, String gateway, String netmask, String vifMacAddress,
Integer nicDevId, boolean newNic) { Integer nicDevId, boolean newNic, String nwType) {
super(); super();
this.publicIp = publicIp; this.publicIp = publicIp;
this.sourceNat = sourceNat; this.sourceNat = sourceNat;
@ -49,6 +50,7 @@ public class IpAddress {
this.vifMacAddress = vifMacAddress; this.vifMacAddress = vifMacAddress;
this.nicDevId = nicDevId; this.nicDevId = nicDevId;
this.newNic = newNic; this.newNic = newNic;
this.nwType = nwType;
} }
public String getPublicIp() { public String getPublicIp() {

View File

@ -57,6 +57,7 @@ import com.cloud.agent.resource.virtualnetwork.model.IpAssociation;
import com.cloud.agent.resource.virtualnetwork.model.LoadBalancerRule; import com.cloud.agent.resource.virtualnetwork.model.LoadBalancerRule;
import com.cloud.agent.resource.virtualnetwork.model.LoadBalancerRules; import com.cloud.agent.resource.virtualnetwork.model.LoadBalancerRules;
import com.cloud.network.lb.LoadBalancingRule.LbDestination; import com.cloud.network.lb.LoadBalancingRule.LbDestination;
import com.cloud.network.Networks.TrafficType;
public class ConfigHelperTest { public class ConfigHelperTest {
@ -272,9 +273,15 @@ public class ConfigHelperTest {
protected IpAssocVpcCommand generateIpAssocVpcCommand() { protected IpAssocVpcCommand generateIpAssocVpcCommand() {
final List<IpAddressTO> ips = new ArrayList<IpAddressTO>(); final List<IpAddressTO> ips = new ArrayList<IpAddressTO>();
ips.add(new IpAddressTO(1, "64.1.1.10", true, true, true, "vlan://64", "64.1.1.1", "255.255.255.0", "01:23:45:67:89:AB", 1000, false)); IpAddressTO ip1 = new IpAddressTO(1, "64.1.1.10", true, true, true, "vlan://64", "64.1.1.1", "255.255.255.0", "01:23:45:67:89:AB", 1000, false);
ips.add(new IpAddressTO(2, "64.1.1.11", false, false, true, "vlan://64", "64.1.1.1", "255.255.255.0", "01:23:45:67:89:AB", 1000, false)); IpAddressTO ip2 = new IpAddressTO(2, "64.1.1.11", false, false, true, "vlan://64", "64.1.1.1", "255.255.255.0", "01:23:45:67:89:AB", 1000, false);
ips.add(new IpAddressTO(3, "65.1.1.11", true, false, false, "vlan://65", "65.1.1.1", "255.255.255.0", "11:23:45:67:89:AB", 1000, false)); IpAddressTO ip3 = new IpAddressTO(3, "65.1.1.11", true, false, false, "vlan://65", "65.1.1.1", "255.255.255.0", "11:23:45:67:89:AB", 1000, false);
ip1.setTrafficType(TrafficType.Public);
ip2.setTrafficType(TrafficType.Public);
ip3.setTrafficType(TrafficType.Public);
ips.add(ip1);
ips.add(ip2);
ips.add(ip3);
final IpAddressTO[] ipArray = ips.toArray(new IpAddressTO[ips.size()]); final IpAddressTO[] ipArray = ips.toArray(new IpAddressTO[ips.size()]);
final IpAssocVpcCommand cmd = new IpAssocVpcCommand(ipArray); final IpAssocVpcCommand cmd = new IpAssocVpcCommand(ipArray);

View File

@ -38,6 +38,7 @@ import com.cloud.hypervisor.ovm3.objects.XmlTestResultTest;
import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3Configuration; import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3Configuration;
import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3ConfigurationTest; import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3ConfigurationTest;
import com.cloud.hypervisor.ovm3.support.Ovm3SupportTest; import com.cloud.hypervisor.ovm3.support.Ovm3SupportTest;
import com.cloud.network.Networks.TrafficType;
import com.cloud.utils.ExecutionResult; import com.cloud.utils.ExecutionResult;
public class Ovm3VirtualRoutingResourceTest { public class Ovm3VirtualRoutingResourceTest {
@ -206,6 +207,7 @@ public class Ovm3VirtualRoutingResourceTest {
List<IpAddressTO> ips = new ArrayList<IpAddressTO>(); List<IpAddressTO> ips = new ArrayList<IpAddressTO>();
IpAddressTO ip = new IpAddressTO(1, routerip, true, true, true, "vlan://" IpAddressTO ip = new IpAddressTO(1, routerip, true, true, true, "vlan://"
+ br[1], "64.1.1.1", "255.255.255.0", mac, 1000, false); + br[1], "64.1.1.1", "255.255.255.0", mac, 1000, false);
ip.setTrafficType(TrafficType.Public);
ips.add(ip); ips.add(ip);
IpAddressTO[] ipArray = ips.toArray(new IpAddressTO[ips.size()]); IpAddressTO[] ipArray = ips.toArray(new IpAddressTO[ips.size()]);
return ipArray; return ipArray;

View File

@ -883,6 +883,12 @@ class CsForwardingRules(CsDataBag):
device = self.getDeviceByIp(rule["public_ip"]) device = self.getDeviceByIp(rule["public_ip"])
if device is None: if device is None:
raise Exception("Ip address %s has no device in the ips databag" % rule["public_ip"]) raise Exception("Ip address %s has no device in the ips databag" % rule["public_ip"])
self.fw.append(["mangle", "",
"-A PREROUTING -s %s/32 -m state --state NEW -j MARK --set-xmark 0x%s/0xffffffff" % \
(rule["internal_ip"], device[len("eth"):])])
self.fw.append(["mangle", "",
"-A PREROUTING -s %s/32 -m state --state NEW -j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff" % \
rule["internal_ip"]])
self.fw.append(["nat", "front", self.fw.append(["nat", "front",
"-A PREROUTING -d %s/32 -j DNAT --to-destination %s" % (rule["public_ip"], rule["internal_ip"])]) "-A PREROUTING -d %s/32 -j DNAT --to-destination %s" % (rule["public_ip"], rule["internal_ip"])])
self.fw.append(["nat", "front", self.fw.append(["nat", "front",

View File

@ -277,9 +277,10 @@ class CsIP:
except Exception as e: except Exception as e:
logging.info("Exception occurred ==> %s" % e) logging.info("Exception occurred ==> %s" % e)
else:
self.delete(self.ip())
self.post_configure(address) self.post_configure(address)
else:
# delete method performs post_configure, so no need to call post_configure here
self.delete(self.ip())
def post_configure(self, address): def post_configure(self, address):
""" The steps that must be done after a device is configured """ """ The steps that must be done after a device is configured """
@ -291,6 +292,9 @@ class CsIP:
interfaces = [CsInterface(address, self.config)] interfaces = [CsInterface(address, self.config)]
CsHelper.reconfigure_interfaces(self.cl, interfaces) CsHelper.reconfigure_interfaces(self.cl, interfaces)
if not self.config.is_vpc() and (self.get_type() in ['public']):
self.set_mark()
if self.config.is_vpc() and (self.get_type() in ['public']):
self.set_mark() self.set_mark()
if 'gateway' in self.address: if 'gateway' in self.address:
@ -386,6 +390,10 @@ class CsIP:
"-j CONNMARK --set-xmark %s/0xffffffff" % self.dnum]) "-j CONNMARK --set-xmark %s/0xffffffff" % self.dnum])
self.fw.append( self.fw.append(
["mangle", "", "-A FIREWALL_%s -j DROP" % self.address['public_ip']]) ["mangle", "", "-A FIREWALL_%s -j DROP" % self.address['public_ip']])
self.fw.append(["filter", "",
"-A FORWARD -i %s -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT" % self.dev])
self.fw.append(["filter", "",
"-A FORWARD -i eth0 -o %s -j FW_OUTBOUND" % self.dev])
self.fw.append(["filter", "", "-A INPUT -d 224.0.0.18/32 -j ACCEPT"]) self.fw.append(["filter", "", "-A INPUT -d 224.0.0.18/32 -j ACCEPT"])
self.fw.append(["filter", "", "-A INPUT -d 225.0.0.50/32 -j ACCEPT"]) self.fw.append(["filter", "", "-A INPUT -d 225.0.0.50/32 -j ACCEPT"])
@ -410,15 +418,8 @@ class CsIP:
["filter", "", "-A FORWARD -i %s -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT" % self.dev]) ["filter", "", "-A FORWARD -i %s -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT" % self.dev])
self.fw.append( self.fw.append(
["filter", "", "-A FORWARD -i %s -o %s -m state --state NEW -j ACCEPT" % (self.dev, self.dev)]) ["filter", "", "-A FORWARD -i %s -o %s -m state --state NEW -j ACCEPT" % (self.dev, self.dev)])
self.fw.append(
["filter", "", "-A FORWARD -i eth2 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT"])
self.fw.append( self.fw.append(
["filter", "", "-A FORWARD -i eth0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT"]) ["filter", "", "-A FORWARD -i eth0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT"])
self.fw.append(
["filter", "", "-A FORWARD -i eth0 -o eth2 -j FW_OUTBOUND"])
self.fw.append(["mangle", "",
"-A PREROUTING -i %s -m state --state NEW " % self.dev +
"-j CONNMARK --set-xmark %s/0xffffffff" % self.dnum])
self.fw.append(['', 'front', '-A FORWARD -j NETWORK_STATS']) self.fw.append(['', 'front', '-A FORWARD -j NETWORK_STATS'])
self.fw.append(['', 'front', '-A INPUT -j NETWORK_STATS']) self.fw.append(['', 'front', '-A INPUT -j NETWORK_STATS'])
@ -431,13 +432,13 @@ class CsIP:
def fw_vpcrouter(self): def fw_vpcrouter(self):
if not self.config.is_vpc(): if not self.config.is_vpc():
return return
self.fw.append(["mangle", "front", "-A PREROUTING " +
"-m state --state RELATED,ESTABLISHED " +
"-j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff"])
self.fw.append(["filter", "", "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT"]) self.fw.append(["filter", "", "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT"])
if self.get_type() in ["guest"]: if self.get_type() in ["guest"]:
self.fw.append(["mangle", "front", "-A PREROUTING " +
" -i %s -m state --state RELATED,ESTABLISHED " % self.dev +
"-j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff"])
guestNetworkCidr = self.address['network'] guestNetworkCidr = self.address['network']
self.fw.append(["filter", "", "-A FORWARD -d %s -o %s -j ACL_INBOUND_%s" % self.fw.append(["filter", "", "-A FORWARD -d %s -o %s -j ACL_INBOUND_%s" %
(guestNetworkCidr, self.dev, self.dev)]) (guestNetworkCidr, self.dev, self.dev)])
@ -515,11 +516,36 @@ class CsIP:
def post_config_change(self, method): def post_config_change(self, method):
route = CsRoute() route = CsRoute()
tableName = "Table_" + self.dev
if method == "add": if method == "add":
route.add_table(self.dev) if not self.config.is_vpc():
route.add_route(self.dev, str(self.address["network"])) # treat the first IP on a interface as special case to set up the routing rules
if self.get_type() in ["public"] and (len(self.iplist) == 1):
CsHelper.execute("sudo ip route add throw " + self.config.address().dbag['eth0'][0]['network'] + " table " + tableName + " proto static")
CsHelper.execute("sudo ip route add throw " + self.config.address().dbag['eth1'][0]['network'] + " table " + tableName + " proto static")
# add 'defaul via gateway' rule in the device specific routing table
if "gateway" in self.address and self.address["gateway"] != "None":
route.add_route(self.dev, self.address["gateway"])
if self.get_type() in ["public"]:
CsRule(self.dev).addRule("from " + str(self.address["network"]))
if self.config.is_vpc():
if self.get_type() in ["public"] and "gateway" in self.address and self.address["gateway"] != "None":
route.add_route(self.dev, self.address["gateway"])
route.add_network_route(self.dev, str(self.address["network"]))
CsHelper.execute("sudo ip route flush cache")
elif method == "delete": elif method == "delete":
logging.warn("delete route not implemented") # treat the last IP to be dis-associated with interface as special case to clean up the routing rules
if self.get_type() in ["public"] and (not self.config.is_vpc()) and (len(self.iplist) == 0):
CsHelper.execute("sudo ip rule delete table " + tableName)
CsHelper.execute("sudo ip route flush table " + tableName)
CsHelper.execute("sudo ip route flush cache")
CsRule(self.dev).delMark()
self.fw_router() self.fw_router()
self.fw_vpcrouter() self.fw_vpcrouter()
@ -558,14 +584,7 @@ class CsIP:
for i in CsHelper.execute(cmd): for i in CsHelper.execute(cmd):
vals = i.lstrip().split() vals = i.lstrip().split()
if (vals[0] == 'inet'): if (vals[0] == 'inet'):
cidr = vals[1] cidr = vals[1]
for ip, device in self.iplist.iteritems():
logging.info(
"Iterating over the existing IPs. CIDR to be configured ==> %s, existing IP ==> %s on device ==> %s",
cidr, ip, device)
if cidr[0] != ip[0] and device != self.dev:
self.iplist[cidr] = self.dev self.iplist[cidr] = self.dev
def configured(self): def configured(self):

View File

@ -36,13 +36,28 @@ class CsRoute:
filename = "/etc/iproute2/rt_tables" filename = "/etc/iproute2/rt_tables"
logging.info( logging.info(
"Adding route table: " + str + " to " + filename + " if not present ") "Adding route table: " + str + " to " + filename + " if not present ")
CsHelper.addifmissing(filename, str) if not CsHelper.definedinfile(filename, str):
CsHelper.execute("sudo echo " + str + " >> /etc/iproute2/rt_tables")
# remove "from all table tablename" if exists, else it will interfer with
# routing of unintended traffic
if self.findRule("from all lookup " + tablename):
CsHelper.execute("sudo ip rule delete from all table " + tablename)
def flush_table(self, tablename): def flush_table(self, tablename):
CsHelper.execute("ip route flush table %s" % (tablename)) CsHelper.execute("ip route flush table %s" % (tablename))
CsHelper.execute("ip route flush cache") CsHelper.execute("ip route flush cache")
def add_route(self, dev, address): def add_route(self, dev, address):
""" Wrapper method that adds table name and device to route statement """
# ip route add dev eth1 table Table_eth1 10.0.2.0/24
table = self.get_tablename(dev)
logging.info("Adding route: dev " + dev + " table: " +
table + " network: " + address + " if not present")
cmd = "dev %s table %s %s" % (dev, table, address)
cmd = "default via %s table %s proto static" % (address, table)
self.set_route(cmd)
def add_network_route(self, dev, address):
""" Wrapper method that adds table name and device to route statement """ """ Wrapper method that adds table name and device to route statement """
# ip route add dev eth1 table Table_eth1 10.0.2.0/24 # ip route add dev eth1 table Table_eth1 10.0.2.0/24
table = self.get_tablename(dev) table = self.get_tablename(dev)
@ -95,3 +110,9 @@ class CsRoute:
else: else:
logging.warn("No default route found!") logging.warn("No default route found!")
return False return False
def findRule(self, rule):
for i in CsHelper.execute("ip rule show"):
if rule in i.strip():
return True
return False

View File

@ -30,12 +30,30 @@ class CsRule:
self.tableNo = int(dev[3:]) self.tableNo = int(dev[3:])
self.table = "Table_%s" % (dev) self.table = "Table_%s" % (dev)
def addRule(self, rule):
if not self.findRule(rule + " lookup " + self.table):
cmd = "ip rule add " + rule + " table " + self.table
CsHelper.execute(cmd)
logging.info("Added rule %s for %s" % (cmd, self.table))
def findRule(self, rule):
for i in CsHelper.execute("ip rule show"):
if rule in i.strip():
return True
return False
def addMark(self): def addMark(self):
if not self.findMark(): if not self.findMark():
cmd = "ip rule add fwmark %s table %s" % (self.tableNo, self.table) cmd = "ip rule add fwmark %s table %s" % (self.tableNo, self.table)
CsHelper.execute(cmd) CsHelper.execute(cmd)
logging.info("Added fwmark rule for %s" % (self.table)) logging.info("Added fwmark rule for %s" % (self.table))
def delMark(self):
if self.findMark():
cmd = "ip rule delete fwmark %s table %s" % (self.tableNo, self.table)
CsHelper.execute(cmd)
logging.info("Deleting fwmark rule for %s" % (self.table))
def findMark(self): def findMark(self):
srch = "from all fwmark %s lookup %s" % (hex(self.tableNo), self.table) srch = "from all fwmark %s lookup %s" % (hex(self.tableNo), self.table)
for i in CsHelper.execute("ip rule show"): for i in CsHelper.execute("ip rule show"):

View File

@ -21,15 +21,20 @@ from netaddr import *
def merge(dbag, ip): def merge(dbag, ip):
added = False added = False
nic_dev_id = None
for dev in dbag: for dev in dbag:
if dev == "id": if dev == "id":
continue continue
for address in dbag[dev]: for address in dbag[dev]:
if address['public_ip'] == ip['public_ip']: if address['public_ip'] == ip['public_ip']:
if 'nic_dev_id' in address:
nic_dev_id = address['nic_dev_id']
dbag[dev].remove(address) dbag[dev].remove(address)
ipo = IPNetwork(ip['public_ip'] + '/' + ip['netmask']) ipo = IPNetwork(ip['public_ip'] + '/' + ip['netmask'])
ip['device'] = 'eth' + str(ip['nic_dev_id']) if 'nic_dev_id' in ip:
nic_dev_id = ip['nic_dev_id']
ip['device'] = 'eth' + str(nic_dev_id)
ip['broadcast'] = str(ipo.broadcast) ip['broadcast'] = str(ipo.broadcast)
ip['cidr'] = str(ipo.ip) + '/' + str(ipo.prefixlen) ip['cidr'] = str(ipo.ip) + '/' + str(ipo.prefixlen)
ip['size'] = str(ipo.prefixlen) ip['size'] = str(ipo.prefixlen)
@ -37,8 +42,8 @@ def merge(dbag, ip):
if 'nw_type' not in ip.keys(): if 'nw_type' not in ip.keys():
ip['nw_type'] = 'public' ip['nw_type'] = 'public'
if ip['nw_type'] == 'control': if ip['nw_type'] == 'control':
dbag['eth' + str(ip['nic_dev_id'])] = [ip] dbag['eth' + str(nic_dev_id)] = [ip]
else: else:
dbag.setdefault('eth' + str(ip['nic_dev_id']), []).append(ip) dbag.setdefault('eth' + str(nic_dev_id), []).append(ip)
return dbag return dbag

File diff suppressed because it is too large Load Diff