kvm: Add usermode interface option to Libvirt Domain XML builder (#6640)

This PR provides constructors and the associated changes to use LibvirtVMDef for creating user mode network interfaces.

While this isn't used directly in the CloudStack KVM agent today, it could be used in the future for e.g. pod networking/management networks without needing to assign a pod IP. The VIF driver used by the CloudStack Agent is also pluggable, so this allows plugin code to create user mode network interfaces as well.

Note that the user mode network already exists in the GuestNetType enum, but wasn't usable prior to this change.

Also included unit test to ensure we continue to create the expected XML.

Additionally, this uncovered a null pointer on _networkRateKBps and this PR fixes it. The decision to add bandwidth throttling assumes this field is not null and simply checks for > 0.

Signed-off-by: Marcus Sorensen <mls@apple.com>
Co-authored-by: Marcus Sorensen <mls@apple.com>
This commit is contained in:
Marcus Sorensen 2022-08-18 01:44:50 -06:00 committed by GitHub
parent 83008e55cf
commit f23a4db6d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 3 deletions

View File

@ -1188,7 +1188,7 @@ public class LibvirtVMDef {
private String _ipAddr;
private String _scriptPath;
private NicModel _model;
private Integer _networkRateKBps;
private int _networkRateKBps;
private String _virtualPortType;
private String _virtualPortInterfaceId;
private int _vlanTag = -1;
@ -1199,11 +1199,27 @@ public class LibvirtVMDef {
private String _dpdkSourcePort;
private String _dpdkExtraLines;
private String _interfaceMode;
private String _userIp4Network;
private Integer _userIp4Prefix;
public void defBridgeNet(String brName, String targetBrName, String macAddr, NicModel model) {
defBridgeNet(brName, targetBrName, macAddr, model, 0);
}
public void defUserNet(NicModel model, String macAddr, String ip4Network, Integer ip4Prefix) {
_netType = GuestNetType.USER;
_macAddr = macAddr;
_userIp4Network = ip4Network;
_userIp4Prefix = ip4Prefix;
_model = model;
}
public void defUserNet(NicModel model, String macAddr) {
_netType = GuestNetType.USER;
_macAddr = macAddr;
_model = model;
}
public void defBridgeNet(String brName, String targetBrName, String macAddr, NicModel model, Integer networkRateKBps) {
_netType = GuestNetType.BRIDGE;
_sourceName = brName;
@ -1385,6 +1401,7 @@ public class LibvirtVMDef {
netBuilder.append("<source type='unix' path='"+ _dpdkSourcePath + _dpdkSourcePort +
"' mode='" + _interfaceMode + "'/>\n");
}
if (_networkName != null) {
netBuilder.append("<target dev='" + _networkName + "'/>\n");
}
@ -1421,13 +1438,18 @@ public class LibvirtVMDef {
netBuilder.append(_dpdkExtraLines);
}
if (_netType != GuestNetType.VHOSTUSER) {
if (_netType != GuestNetType.VHOSTUSER && _netType != GuestNetType.USER) {
netBuilder.append("<link state='" + (_linkStateUp ? "up" : "down") +"'/>\n");
}
if (_slot != null) {
netBuilder.append(String.format("<address type='pci' domain='0x0000' bus='0x00' slot='0x%02x' function='0x0'/>\n", _slot));
}
if (StringUtils.isNotBlank(_userIp4Network) && _userIp4Prefix != null) {
netBuilder.append(String.format("<ip family='ipv4' address='%s' prefix='%s'/>\n", _userIp4Network, _userIp4Prefix));
}
return netBuilder.toString();
}

View File

@ -56,7 +56,34 @@ public class LibvirtVMDefTest extends TestCase {
}
@Test
public void testInterfaceEtehrnet() {
public void testInterfaceTypeUserWithNetwork() {
LibvirtVMDef.InterfaceDef interfaceDef = new LibvirtVMDef.InterfaceDef();
interfaceDef.defUserNet(LibvirtVMDef.InterfaceDef.NicModel.VIRTIO, "00:11:22:aa:bb:dd", "192.168.100.0", 24);
String expected = "<interface type='user'>\n" +
"<mac address='00:11:22:aa:bb:dd'/>\n" +
"<model type='virtio'/>\n" +
"<ip family='ipv4' address='192.168.100.0' prefix='24'/>\n" +
"</interface>\n";
assertEquals(expected, interfaceDef.toString());
}
@Test
public void testInterfaceTypeUserWithoutNetwork() {
LibvirtVMDef.InterfaceDef interfaceDef = new LibvirtVMDef.InterfaceDef();
interfaceDef.defUserNet(LibvirtVMDef.InterfaceDef.NicModel.VIRTIO, "00:11:22:aa:bb:dd");
String expected = "<interface type='user'>\n" +
"<mac address='00:11:22:aa:bb:dd'/>\n" +
"<model type='virtio'/>\n" +
"</interface>\n";
assertEquals(expected, interfaceDef.toString());
}
@Test
public void testInterfaceEthernet() {
LibvirtVMDef.InterfaceDef ifDef = new LibvirtVMDef.InterfaceDef();
ifDef.defEthernet("targetDeviceName", "00:11:22:aa:bb:dd", LibvirtVMDef.InterfaceDef.NicModel.VIRTIO);