Network network = getNetwork(conn, nic);
// Determine the correct VIF on DomR to associate/disassociate the
// IP address with
VIF correctVif = getCorrectVif(conn, router, network);
// If we are associating an IP address and DomR doesn't have a VIF
// for the specified vlan ID, we need to add a VIF
// If we are disassociating the last IP address in the VLAN, we need
// to remove a VIF
boolean addVif = false;
boolean removeVif = false;
if (add && correctVif == null) {
addVif = true;
}
if (!add && correctVif == null) {
return; // it is a disassociateIp and it has already happened
}
if (addVif) {
// Add a new VIF to DomR
String vifDeviceNum = getLowestAvailableVIFDeviceNum(conn, router);
if (vifDeviceNum == null) {
throw new InternalErrorException("There were no more available slots for a new VIF on router: " + router.getNameLabel(conn));
}
nic.setDeviceId(Integer.parseInt(vifDeviceNum));
correctVif = createVif(conn, vmName, router, nic);
correctVif.plug(conn);
// Add iptables rule for network usage
networkUsage(conn, privateIpAddress, "addVif", "eth" + correctVif.getDevice(conn));
}
if (correctVif == null) {
throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with.");
}
String args = "ipassoc.sh " + privateIpAddress;
if (add) {
args += " -A ";
} else {
args += " -D ";
}
if (sourceNat) {
args += " -s";
}
if (firstIP) {
args += " -f";
}
String cidrSize = Long.toString(NetUtils.getCidrSize(vlanNetmask));
args += " -l ";
args += publicIpAddress + "/" + cidrSize;
args += " -c ";
args += "eth" + correctVif.getDevice(conn);
args += " -g ";
args += vlanGateway;
if (addVif) {
//To indicate this is new interface created
args += " -n";
}
String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args);
if (result == null || result.isEmpty()) {
throw new InternalErrorException("Xen plugin \"ipassoc\" failed.");
}
if (!add) {
args += " -d";
String zeroIpsRes = callHostPlugin(conn, "vmops", "routerProxy", "args", args);
if (zeroIpsRes == null || zeroIpsRes.isEmpty()) {
//There are no ip address set on the interface. So unplug the interface
// If it is not unplugged then the interface is not resuable.
removeVif = true;
}
}
if (removeVif) {
network = correctVif.getNetwork(conn);
// Mark this vif to be removed from network usage
networkUsage(conn, privateIpAddress, "deleteVif", "eth" + correctVif.getDevice(conn));
// Remove the VIF from DomR
correctVif.unplug(conn);
correctVif.destroy(conn);
// Disable the VLAN network if necessary
disableVlanNetwork(conn, network);
}