Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion api/src/main/java/com/cloud/network/Network.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
public interface Network extends ControlledEntity, StateObject<Network.State>, InternalIdentity, Identity, Serializable, Displayable {

enum GuestType {
Shared, Isolated, L2;
Shared, Isolated, L2, L3;

public static GuestType fromValue(String type) {
if (StringUtils.isBlank(type)) {
Expand All @@ -54,6 +54,8 @@ public static GuestType fromValue(String type) {
return Isolated;
} else if (type.equalsIgnoreCase("L2")) {
return L2;
} else if (type.equalsIgnoreCase("L3")) {
return L3;
} else {
throw new InvalidParameterValueException("Unexpected Guest type : " + type);
}
Expand Down
17 changes: 17 additions & 0 deletions api/src/main/java/com/cloud/network/Networks.java
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,23 @@ public <T> URI toUri(T value) {
}
}
},
/**
* Direct Routed (L3) networks: the id is a label naming the per-network bridge on the
* hypervisor (brdr-&lt;id&gt;), not an encapsulation — nothing appears on the wire.
*/
Routed("routed", Long.class) {
@Override
public <T> URI toUri(T value) {
try {
if (value.toString().contains("://"))
return new URI(value.toString());
else
return new URI("routed://" + value.toString());
} catch (URISyntaxException e) {
throw new CloudRuntimeException("Unable to convert to broadcast URI: " + value);
}
}
},
UnDecided(null, null),
OpenDaylight("opendaylight", String.class),
TUNGSTEN("tf", String.class),
Expand Down
1 change: 1 addition & 0 deletions api/src/main/java/com/cloud/offering/NetworkOffering.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ enum RoutingMode {
public final static String DefaultL2NetworkOfferingVlan = "DefaultL2NetworkOfferingVlan";
public final static String DefaultL2NetworkOfferingConfigDrive = "DefaultL2NetworkOfferingConfigDrive";
public final static String DefaultL2NetworkOfferingConfigDriveVlan = "DefaultL2NetworkOfferingConfigDriveVlan";
public final static String DefaultL3NetworkOffering = "DefaultL3NetworkOffering";

/**
* @return name for the network offering.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -340,10 +340,10 @@ public Long getPhysicalNetworkId() {
}
}
if (physicalNetworkId != null) {
if ((offering.getGuestType() == GuestType.Shared) || (offering.getGuestType() == GuestType.L2)) {
if ((offering.getGuestType() == GuestType.Shared) || (offering.getGuestType() == GuestType.L2) || (offering.getGuestType() == GuestType.L3)) {
return physicalNetworkId;
} else {
throw new InvalidParameterValueException("Physical network ID can be specified for networks of guest IP type " + GuestType.Shared + " or " + GuestType.L2 + " only.");
throw new InvalidParameterValueException(String.format("Physical network ID can be specified for networks of guest IP type %s, %s or %s only.", GuestType.Shared, GuestType.L2, GuestType.L3));
}
} else {
if (zoneId == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,16 @@ public NetworkType getNetworkType() {
}


/**
* A Direct Routed (L3) network needs the agent told when a secondary IP goes away, so the
* host route and neighbour entry are removed - otherwise the host keeps routing an address
* the Instance no longer owns, and the routing daemon keeps advertising it.
*/
private boolean isDirectRoutedNetwork() {
Network ntwk = _entityMgr.findById(Network.class, getNetworkId());
return ntwk != null && Network.GuestType.L3.equals(ntwk.getGuestType());
}

private boolean isZoneSGEnabled() {
Network ntwk = _entityMgr.findById(Network.class, getNetworkId());
DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId());
Expand All @@ -144,7 +154,7 @@ public void execute() throws InvalidParameterValueException {
secIp = nicSecIp.getIp6Address();
}

if (isZoneSGEnabled()) {
if (isZoneSGEnabled() || isDirectRoutedNetwork()) {
//remove the security group rules for this secondary ip
boolean success = false;
success = _securityGroupService.securityGroupRulesForVmSecIp(nicSecIp.getNicId(), secIp, false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ public void testGetPhysicalNetworkIdForNonSharedNet() {
try {
cmd.getPhysicalNetworkId();
} catch (Exception e) {
Assert.assertTrue(e.getMessage().startsWith("Physical network ID can be specified for networks of guest IP type Shared or L2 only."));
Assert.assertTrue(e.getMessage().startsWith("Physical network ID can be specified for networks of guest IP type Shared, L2 or L3 only."));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,28 @@ public class NetworkRulesVmSecondaryIpCommand extends Command {
private String vmSecIp;
private String vmMac;
private String action;
private boolean directRouted;
private boolean applySecurityGroupRules = true;

public NetworkRulesVmSecondaryIpCommand(String vmName, VirtualMachine.Type type) {
this.vmName = vmName;
this.type = type;
}

public NetworkRulesVmSecondaryIpCommand(String vmName, String vmMac, String secondaryIp, boolean action, boolean directRouted, boolean applySecurityGroupRules) {
this(vmName, vmMac, secondaryIp, action);
this.directRouted = directRouted;
this.applySecurityGroupRules = applySecurityGroupRules;
}

public boolean isDirectRouted() {
return directRouted;
}

public boolean isApplySecurityGroupRules() {
return applySecurityGroupRules;
}

public NetworkRulesVmSecondaryIpCommand(String vmName, String vmMac, String secondaryIp, boolean action) {
this.vmName = vmName;
this.vmMac = vmMac;
Expand Down
Loading
Loading