mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
kvm: Allow Link Local Cidr (cloud0 interface) to be configured (#3500)
There are certain scenarios where the 169.254.0.0/16 subnet is used for different purposes then CloudStack on a hypervisor. Once of such scenarios is a BGP+EVPN+VXLAN setup using BGP Unnumbered where the 169.254.0.1 address is used by Frr/Zebra BGP routing to send traffic to the neighboring router. The following settings can be changed in the agent.properties (default values added): control.cidr=169.254.0.0/16 Make sure the global setting 'control.cidr' matches the values defined in the agent.propeties! In the future the mgmt server can send this parameter to a KVM Agent on startup, but at the moment this framework is not in place and thus these values can't be send to the Agent in a proper manner. Signed-off-by: Wido den Hollander <wido@widodh.nl>
This commit is contained in:
parent
333409a83c
commit
e894658f8c
@ -28,17 +28,17 @@ import java.util.regex.Pattern;
|
||||
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
import com.cloud.utils.script.OutputInterpreter;
|
||||
import com.google.common.base.Strings;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.libvirt.LibvirtException;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import com.cloud.agent.api.to.NicTO;
|
||||
import com.cloud.exception.InternalErrorException;
|
||||
import com.cloud.network.Networks;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
import com.cloud.utils.script.OutputInterpreter;
|
||||
import com.cloud.utils.script.Script;
|
||||
|
||||
public class BridgeVifDriver extends VifDriverBase {
|
||||
@ -49,7 +49,7 @@ public class BridgeVifDriver extends VifDriverBase {
|
||||
private final Object _vnetBridgeMonitor = new Object();
|
||||
private String _modifyVlanPath;
|
||||
private String _modifyVxlanPath;
|
||||
private String bridgeNameSchema;
|
||||
private String _controlCidr = NetUtils.getLinkLocalCIDR();
|
||||
private Long libvirtVersion;
|
||||
|
||||
@Override
|
||||
@ -67,7 +67,10 @@ public class BridgeVifDriver extends VifDriverBase {
|
||||
networkScriptsDir = "scripts/vm/network/vnet";
|
||||
}
|
||||
|
||||
bridgeNameSchema = (String)params.get("network.bridge.name.schema");
|
||||
String controlCidr = (String)params.get("control.cidr");
|
||||
if (StringUtils.isNotBlank(controlCidr)) {
|
||||
_controlCidr = controlCidr;
|
||||
}
|
||||
|
||||
String value = (String)params.get("scripts.timeout");
|
||||
_timeout = NumbersUtil.parseInt(value, 30 * 60) * 1000;
|
||||
@ -384,7 +387,7 @@ public class BridgeVifDriver extends VifDriverBase {
|
||||
private void deleteExistingLinkLocalRouteTable(String linkLocalBr) {
|
||||
Script command = new Script("/bin/bash", _timeout);
|
||||
command.add("-c");
|
||||
command.add("ip route | grep " + NetUtils.getLinkLocalCIDR());
|
||||
command.add("ip route | grep " + _controlCidr);
|
||||
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
|
||||
String result = command.execute(parser);
|
||||
boolean foundLinkLocalBr = false;
|
||||
@ -397,15 +400,16 @@ public class BridgeVifDriver extends VifDriverBase {
|
||||
}
|
||||
final String device = tokens[2];
|
||||
if (!Strings.isNullOrEmpty(device) && !device.equalsIgnoreCase(linkLocalBr)) {
|
||||
Script.runSimpleBashScript("ip route del " + NetUtils.getLinkLocalCIDR() + " dev " + tokens[2]);
|
||||
Script.runSimpleBashScript("ip route del " + _controlCidr + " dev " + tokens[2]);
|
||||
} else {
|
||||
foundLinkLocalBr = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundLinkLocalBr) {
|
||||
Script.runSimpleBashScript("ip address add 169.254.0.1/16 dev " + linkLocalBr + ";" + "ip route add " + NetUtils.getLinkLocalCIDR() + " dev " + linkLocalBr + " src " +
|
||||
NetUtils.getLinkLocalGateway());
|
||||
Script.runSimpleBashScript("ip address add " + NetUtils.getLinkLocalAddressFromCIDR(_controlCidr) + " dev " + linkLocalBr);
|
||||
Script.runSimpleBashScript("ip route add " + _controlCidr + " dev " + linkLocalBr + " src " + NetUtils.getLinkLocalGateway(_controlCidr));
|
||||
}
|
||||
}
|
||||
|
||||
@ -417,7 +421,9 @@ public class BridgeVifDriver extends VifDriverBase {
|
||||
public void createControlNetwork(String privBrName) {
|
||||
deleteExistingLinkLocalRouteTable(privBrName);
|
||||
if (!isExistingBridge(privBrName)) {
|
||||
Script.runSimpleBashScript("brctl addbr " + privBrName + "; ip link set " + privBrName + " up; ip address add 169.254.0.1/16 dev " + privBrName, _timeout);
|
||||
Script.runSimpleBashScript("ip link add name " + privBrName + " type bridge");
|
||||
Script.runSimpleBashScript("ip link set " + privBrName + " up");
|
||||
Script.runSimpleBashScript("ip address add " + NetUtils.getLinkLocalAddressFromCIDR(_controlCidr) + " dev " + privBrName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@ import java.util.regex.Pattern;
|
||||
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.utils.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.libvirt.LibvirtException;
|
||||
|
||||
@ -46,7 +47,7 @@ public class IvsVifDriver extends VifDriverBase {
|
||||
private String _modifyVlanPath;
|
||||
private String _modifyVxlanPath;
|
||||
private String _ivsIfUpPath;
|
||||
private Long libvirtVersion;
|
||||
private String _controlCidr = NetUtils.getLinkLocalCIDR();
|
||||
|
||||
@Override
|
||||
public void configure(Map<String, Object> params) throws ConfigurationException {
|
||||
@ -70,9 +71,9 @@ public class IvsVifDriver extends VifDriverBase {
|
||||
}
|
||||
_ivsIfUpPath = Script.findScript(utilScriptsDir, "qemu-ivs-ifup");
|
||||
|
||||
libvirtVersion = (Long) params.get("libvirtVersion");
|
||||
if (libvirtVersion == null) {
|
||||
libvirtVersion = 0L;
|
||||
String controlCidr = (String)params.get("control.cidr");
|
||||
if (StringUtils.isNotBlank(controlCidr)) {
|
||||
_controlCidr = controlCidr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -256,7 +257,7 @@ public class IvsVifDriver extends VifDriverBase {
|
||||
private void deleteExitingLinkLocalRouteTable(String linkLocalBr) {
|
||||
Script command = new Script("/bin/bash", _timeout);
|
||||
command.add("-c");
|
||||
command.add("ip route | grep " + NetUtils.getLinkLocalCIDR());
|
||||
command.add("ip route | grep " + _controlCidr);
|
||||
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
|
||||
String result = command.execute(parser);
|
||||
boolean foundLinkLocalBr = false;
|
||||
@ -265,15 +266,15 @@ public class IvsVifDriver extends VifDriverBase {
|
||||
for (String line : lines) {
|
||||
String[] tokens = line.split(" ");
|
||||
if (!tokens[2].equalsIgnoreCase(linkLocalBr)) {
|
||||
Script.runSimpleBashScript("ip route del " + NetUtils.getLinkLocalCIDR());
|
||||
Script.runSimpleBashScript("ip route del " + _controlCidr);
|
||||
} else {
|
||||
foundLinkLocalBr = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!foundLinkLocalBr) {
|
||||
Script.runSimpleBashScript("ip address add 169.254.0.1/16 dev " + linkLocalBr + ";" + "ip route add " + NetUtils.getLinkLocalCIDR() + " dev " + linkLocalBr + " src " +
|
||||
NetUtils.getLinkLocalGateway());
|
||||
Script.runSimpleBashScript("ip address add " + NetUtils.getLinkLocalAddressFromCIDR(_controlCidr) + " dev " + linkLocalBr);
|
||||
Script.runSimpleBashScript("ip route add " + _controlCidr + " dev " + linkLocalBr + " src " + NetUtils.getLinkLocalGateway(_controlCidr));
|
||||
}
|
||||
}
|
||||
|
||||
@ -281,7 +282,8 @@ public class IvsVifDriver extends VifDriverBase {
|
||||
public void createControlNetwork(String privBrName) {
|
||||
deleteExitingLinkLocalRouteTable(privBrName);
|
||||
if (!isBridgeExists(privBrName)) {
|
||||
Script.runSimpleBashScript("brctl addbr " + privBrName + "; ip link set " + privBrName + " up; ip address add 169.254.0.1/16 dev " + privBrName, _timeout);
|
||||
Script.runSimpleBashScript("brctl addbr " + privBrName + "; ip link set " + privBrName + " up");
|
||||
Script.runSimpleBashScript("ip address add " + NetUtils.getLinkLocalAddressFromCIDR(_controlCidr) + " dev " + privBrName, _timeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -44,6 +44,7 @@ import com.cloud.utils.script.Script;
|
||||
public class OvsVifDriver extends VifDriverBase {
|
||||
private static final Logger s_logger = Logger.getLogger(OvsVifDriver.class);
|
||||
private int _timeout;
|
||||
private String _controlCidr = NetUtils.getLinkLocalCIDR();
|
||||
private DpdkDriver dpdkDriver;
|
||||
|
||||
@Override
|
||||
@ -62,6 +63,11 @@ public class OvsVifDriver extends VifDriverBase {
|
||||
dpdkDriver = new DpdkDriverImpl();
|
||||
}
|
||||
|
||||
String controlCidr = (String)params.get("control.cidr");
|
||||
if (com.cloud.utils.StringUtils.isNotBlank(controlCidr)) {
|
||||
_controlCidr = controlCidr;
|
||||
}
|
||||
|
||||
String value = (String)params.get("scripts.timeout");
|
||||
_timeout = NumbersUtil.parseInt(value, 30 * 60) * 1000;
|
||||
}
|
||||
@ -213,7 +219,7 @@ public class OvsVifDriver extends VifDriverBase {
|
||||
private void deleteExitingLinkLocalRouteTable(String linkLocalBr) {
|
||||
Script command = new Script("/bin/bash", _timeout);
|
||||
command.add("-c");
|
||||
command.add("ip route | grep " + NetUtils.getLinkLocalCIDR());
|
||||
command.add("ip route | grep " + _controlCidr);
|
||||
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
|
||||
String result = command.execute(parser);
|
||||
boolean foundLinkLocalBr = false;
|
||||
@ -222,15 +228,15 @@ public class OvsVifDriver extends VifDriverBase {
|
||||
for (String line : lines) {
|
||||
String[] tokens = line.split(" ");
|
||||
if (!tokens[2].equalsIgnoreCase(linkLocalBr)) {
|
||||
Script.runSimpleBashScript("ip route del " + NetUtils.getLinkLocalCIDR());
|
||||
Script.runSimpleBashScript("ip route del " + _controlCidr);
|
||||
} else {
|
||||
foundLinkLocalBr = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!foundLinkLocalBr) {
|
||||
Script.runSimpleBashScript("ip address add 169.254.0.1/16 dev " + linkLocalBr + ";" + "ip route add " + NetUtils.getLinkLocalCIDR() + " dev " + linkLocalBr + " src " +
|
||||
NetUtils.getLinkLocalGateway());
|
||||
Script.runSimpleBashScript("ip address add " + NetUtils.getLinkLocalAddressFromCIDR(_controlCidr) + " dev " + linkLocalBr + ";" + "ip route add " + _controlCidr + " dev " + linkLocalBr + " src " +
|
||||
NetUtils.getLinkLocalGateway(_controlCidr));
|
||||
}
|
||||
}
|
||||
|
||||
@ -238,7 +244,7 @@ public class OvsVifDriver extends VifDriverBase {
|
||||
public void createControlNetwork(String privBrName) {
|
||||
deleteExitingLinkLocalRouteTable(privBrName);
|
||||
if (!isExistingBridge(privBrName)) {
|
||||
Script.runSimpleBashScript("ovs-vsctl add-br " + privBrName + "; ip link set " + privBrName + " up; ip address add 169.254.0.1/16 dev " + privBrName, _timeout);
|
||||
Script.runSimpleBashScript("ovs-vsctl add-br " + privBrName + "; ip link set " + privBrName + " up; ip address add " + NetUtils.getLinkLocalAddressFromCIDR(_controlCidr) + " dev " + privBrName, _timeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1613,7 +1613,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
_zoneDao.addPrivateIpAddress(zoneId, pod.getId(), startIp, endIpFinal, false, null);
|
||||
}
|
||||
|
||||
final String[] linkLocalIpRanges = getLinkLocalIPRange();
|
||||
final String[] linkLocalIpRanges = NetUtils.getLinkLocalIPRange(_configDao.getValue(Config.ControlCidr.key()));
|
||||
if (linkLocalIpRanges != null) {
|
||||
_zoneDao.addLinkLocalIpAddress(zoneId, pod.getId(), linkLocalIpRanges[0], linkLocalIpRanges[1]);
|
||||
}
|
||||
@ -4489,20 +4489,6 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
}
|
||||
}
|
||||
|
||||
private String[] getLinkLocalIPRange() {
|
||||
final String ipNums = _configDao.getValue("linkLocalIp.nums");
|
||||
final int nums = Integer.parseInt(ipNums);
|
||||
if (nums > 16 || nums <= 0) {
|
||||
throw new InvalidParameterValueException("The linkLocalIp.nums: " + nums + "is wrong, should be 1~16");
|
||||
}
|
||||
/* local link ip address starts from 169.254.0.2 - 169.254.(nums) */
|
||||
final String[] ipRanges = NetUtils.getLinkLocalIPRange(nums);
|
||||
if (ipRanges == null) {
|
||||
throw new InvalidParameterValueException("The linkLocalIp.nums: " + nums + "may be wrong, should be 1~16");
|
||||
}
|
||||
return ipRanges;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_VLAN_IP_RANGE_DELETE, eventDescription = "deleting vlan ip range", async = false)
|
||||
public boolean deleteVlanIpRange(final DeleteVlanIpRangeCmd cmd) {
|
||||
|
||||
@ -160,11 +160,16 @@ public class ControlNetworkGuru extends PodBasedNetworkGuru implements NetworkGu
|
||||
if (ip == null) {
|
||||
throw new InsufficientAddressCapacityException("Insufficient link local address capacity", DataCenter.class, dest.getDataCenter().getId());
|
||||
}
|
||||
|
||||
String netmask = NetUtils.cidr2Netmask(_cidr);
|
||||
|
||||
s_logger.debug(String.format("Reserved NIC for %s [ipv4:%s netmask:%s gateway:%s]", vm.getInstanceName(), ip, netmask, _gateway));
|
||||
|
||||
nic.setIPv4Address(ip);
|
||||
nic.setMacAddress(NetUtils.long2Mac(NetUtils.ip2Long(ip) | (14l << 40)));
|
||||
nic.setIPv4Netmask("255.255.0.0");
|
||||
nic.setIPv4Netmask(netmask);
|
||||
nic.setFormat(AddressFormat.Ip4);
|
||||
nic.setIPv4Gateway(NetUtils.getLinkLocalGateway());
|
||||
nic.setIPv4Gateway(_gateway);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -223,7 +228,7 @@ public class ControlNetworkGuru extends PodBasedNetworkGuru implements NetworkGu
|
||||
|
||||
_cidr = dbParams.get(Config.ControlCidr.toString());
|
||||
if (_cidr == null) {
|
||||
_cidr = "169.254.0.0/16";
|
||||
_cidr = NetUtils.getLinkLocalCIDR();
|
||||
}
|
||||
|
||||
_gateway = dbParams.get(Config.ControlGateway.toString());
|
||||
|
||||
@ -904,12 +904,8 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio
|
||||
throw new InvalidParameterValueException("The linkLocalIp.nums: " + nums + "is wrong, should be 1~16");
|
||||
}
|
||||
/* local link ip address starts from 169.254.0.2 - 169.254.(nums) */
|
||||
String[] linkLocalIpRanges = NetUtils.getLinkLocalIPRange(nums);
|
||||
if (linkLocalIpRanges == null) {
|
||||
throw new InvalidParameterValueException("The linkLocalIp.nums: " + nums + "may be wrong, should be 1~16");
|
||||
} else {
|
||||
_zoneDao.addLinkLocalIpAddress(zoneId, pod.getId(), linkLocalIpRanges[0], linkLocalIpRanges[1]);
|
||||
}
|
||||
String[] linkLocalIpRanges = NetUtils.getLinkLocalIPRange(_configDao.getValue(Config.ControlCidr.key()));
|
||||
_zoneDao.addLinkLocalIpAddress(zoneId, pod.getId(), linkLocalIpRanges[0], linkLocalIpRanges[1]);
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
|
||||
@ -436,7 +436,7 @@ public class IPRangeConfig {
|
||||
problemIPs = savePrivateIPRange(txn, startIPLong, endIPLong, podId, zoneId);
|
||||
}
|
||||
|
||||
String[] linkLocalIps = NetUtils.getLinkLocalIPRange(10);
|
||||
String[] linkLocalIps = NetUtils.getLinkLocalIPRange("169.254.0.0/16");
|
||||
long startLinkLocalIp = NetUtils.ip2Long(linkLocalIps[0]);
|
||||
long endLinkLocalIp = NetUtils.ip2Long(linkLocalIps[1]);
|
||||
|
||||
|
||||
@ -961,27 +961,34 @@ public class NetUtils {
|
||||
return "255.255.0.0";
|
||||
}
|
||||
|
||||
public static String getLinkLocalGateway(String cidr) {
|
||||
return getLinkLocalFirstAddressFromCIDR(cidr);
|
||||
}
|
||||
|
||||
public static String getLinkLocalGateway() {
|
||||
return "169.254.0.1";
|
||||
return getLinkLocalGateway(getLinkLocalCIDR());
|
||||
}
|
||||
|
||||
public static String getLinkLocalCIDR() {
|
||||
return "169.254.0.0/16";
|
||||
}
|
||||
|
||||
public static String[] getLinkLocalIPRange(final int size) {
|
||||
if (size > 16 || size <= 0) {
|
||||
return null;
|
||||
}
|
||||
/* reserve gateway */
|
||||
final String[] range = getIpRangeFromCidr(getLinkLocalGateway(), MAX_CIDR - size);
|
||||
public static String getLinkLocalFirstAddressFromCIDR(final String cidr) {
|
||||
SubnetUtils subnetUtils = new SubnetUtils(cidr);
|
||||
return subnetUtils.getInfo().getLowAddress();
|
||||
}
|
||||
|
||||
public static String getLinkLocalAddressFromCIDR(final String cidr) {
|
||||
return getLinkLocalFirstAddressFromCIDR(cidr) + "/" + cidr2Netmask(cidr);
|
||||
}
|
||||
|
||||
public static String[] getLinkLocalIPRange(final String cidr) {
|
||||
final SubnetUtils subnetUtils = new SubnetUtils(cidr);
|
||||
final String[] addresses = subnetUtils.getInfo().getAllAddresses();
|
||||
final String[] range = new String[2];
|
||||
range[0] = addresses[1];
|
||||
range[1] = subnetUtils.getInfo().getHighAddress();
|
||||
|
||||
if (range[0].equalsIgnoreCase(getLinkLocalGateway())) {
|
||||
/* remove the gateway */
|
||||
long ip = ip2Long(range[0]);
|
||||
ip += 1;
|
||||
range[0] = long2Ip(ip);
|
||||
}
|
||||
return range;
|
||||
}
|
||||
|
||||
|
||||
@ -709,4 +709,26 @@ public class NetUtilsTest {
|
||||
assertFalse(NetUtils.isIPv6EUI64("2001:db8::100:1"));
|
||||
assertFalse(NetUtils.isIPv6EUI64("2a01:4f9:2a:185f::2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLinkLocal() {
|
||||
final String cidr = NetUtils.getLinkLocalCIDR();
|
||||
assertEquals("255.255.0.0", NetUtils.getLinkLocalNetMask());
|
||||
assertEquals("169.254.0.1", NetUtils.getLinkLocalGateway());
|
||||
assertEquals("169.254.0.0/16", cidr);
|
||||
assertEquals("169.254.0.1", NetUtils.getLinkLocalFirstAddressFromCIDR(cidr));
|
||||
assertEquals("169.254.0.1/255.255.0.0", NetUtils.getLinkLocalAddressFromCIDR(cidr));
|
||||
assertEquals("169.254.240.1/255.255.240.0", NetUtils.getLinkLocalAddressFromCIDR("169.254.240.0/20"));
|
||||
|
||||
String[] range = NetUtils.getLinkLocalIPRange("169.254.0.0/16");
|
||||
assertEquals("169.254.0.2", range[0]);
|
||||
assertEquals("169.254.255.254", range[1]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCidrNetmask() {
|
||||
assertEquals("255.255.255.0", NetUtils.cidr2Netmask("192.168.0.0/24"));
|
||||
assertEquals("255.255.0.0", NetUtils.cidr2Netmask("169.254.0.0/16"));
|
||||
assertEquals("255.255.240.0", NetUtils.cidr2Netmask("169.254.240.0/20"));
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user