org.opendaylight.netvirt.neutronvpn.NeutronQosUtils Maven / Gradle / Ivy
/*
* Copyright (c) 2016 Intel Corporation and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.netvirt.neutronvpn;
import com.google.common.base.Optional;
import java.math.BigInteger;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.BridgeInterfaceInfo;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.BridgeRefInfo;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.BridgeEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.BridgeEntryKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntryKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.qos.ext.rev160613.QosNetworkExtension;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.qos.ext.rev160613.QosPortExtension;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.qos.rev160613.qos.attributes.qos.policies.QosPolicy;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.qos.rev160613.qos.attributes.qos.policies.qos.policy.BandwidthLimitRules;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.qos.rev160613.qos.attributes.qos.policies.qos.policy.BandwidthLimitRulesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class NeutronQosUtils {
private static final Logger LOG = LoggerFactory.getLogger(NeutronQosUtils.class);
private static final String EXTERNAL_ID_INTERFACE_ID = "iface-id";
public static void handleNeutronPortQosUpdate(DataBroker db, OdlInterfaceRpcService odlInterfaceRpcService,
Port port, Uuid qosUuid) {
LOG.trace("Handling Port QoS update: port: {} qos: {}", port.getUuid(), qosUuid);
// handle Bandwidth Limit Rules update
QosPolicy qosPolicy = NeutronvpnUtils.qosPolicyMap.get(qosUuid);
if (qosPolicy != null && qosPolicy.getBandwidthLimitRules() != null
&& !qosPolicy.getBandwidthLimitRules().isEmpty()) {
setPortBandwidthLimits(db, odlInterfaceRpcService, port,
qosPolicy.getBandwidthLimitRules().get(0));
}
}
public static void handleNeutronPortQosRemove(DataBroker db, OdlInterfaceRpcService odlInterfaceRpcService,
Port port, Uuid qosUuid) {
LOG.trace("Handling Port QoS removal: port: {} qos: {}", port.getUuid(), qosUuid);
// handle Bandwidth Limit Rules removal
QosPolicy qosPolicy = NeutronvpnUtils.qosPolicyMap.get(qosUuid);
if (qosPolicy != null && qosPolicy.getBandwidthLimitRules() != null
&& !qosPolicy.getBandwidthLimitRules().isEmpty()) {
BandwidthLimitRulesBuilder bwLimitBuilder = new BandwidthLimitRulesBuilder();
setPortBandwidthLimits(db, odlInterfaceRpcService, port,
bwLimitBuilder.setMaxBurstKbps(BigInteger.ZERO).setMaxKbps(BigInteger.ZERO).build());
}
// check for network qos to apply
Network network = NeutronvpnUtils.getNeutronNetwork(db, port.getNetworkId());
if (network != null && network.getAugmentation(QosNetworkExtension.class) != null) {
Uuid networkQosUuid = network.getAugmentation(QosNetworkExtension.class).getQosPolicyId();
if (networkQosUuid != null) {
handleNeutronPortQosUpdate(db, odlInterfaceRpcService, port, networkQosUuid);
}
}
}
public static void handleNeutronNetworkQosUpdate(DataBroker db, OdlInterfaceRpcService odlInterfaceRpcService,
Network network, Uuid qosUuid) {
LOG.trace("Handling Network QoS update: net: {} qos: {}", network.getUuid(), qosUuid);
QosPolicy qosPolicy = NeutronvpnUtils.qosPolicyMap.get(qosUuid);
if (qosPolicy == null || qosPolicy.getBandwidthLimitRules() == null
|| qosPolicy.getBandwidthLimitRules().isEmpty()) {
return;
}
List subnetIds = NeutronvpnUtils.getSubnetIdsFromNetworkId(db, network.getUuid());
if (subnetIds != null) {
for (Uuid subnetId : subnetIds) {
List portIds = NeutronvpnUtils.getPortIdsFromSubnetId(db, subnetId);
if (portIds != null) {
for (Uuid portId : portIds) {
Port port = NeutronvpnUtils.portMap.get(portId);
if (port != null && (port.getAugmentation(QosPortExtension.class) == null
|| port.getAugmentation(QosPortExtension.class).getQosPolicyId() == null)) {
setPortBandwidthLimits(db, odlInterfaceRpcService, port,
qosPolicy.getBandwidthLimitRules().get(0));
}
}
}
}
}
}
public static void handleNeutronNetworkQosRemove(DataBroker db, OdlInterfaceRpcService odlInterfaceRpcService,
Network network, Uuid qosUuid) {
LOG.trace("Handling Network QoS removal: net: {} qos: {}", network.getUuid(), qosUuid);
List subnetIds = NeutronvpnUtils.getSubnetIdsFromNetworkId(db, network.getUuid());
if (subnetIds != null) {
for (Uuid subnetId : subnetIds) {
List portIds = NeutronvpnUtils.getPortIdsFromSubnetId(db, subnetId);
if (portIds != null) {
for (Uuid portId : portIds) {
Port port = NeutronvpnUtils.portMap.get(portId);
if (port != null && (port.getAugmentation(QosPortExtension.class) == null
|| port.getAugmentation(QosPortExtension.class).getQosPolicyId() == null)) {
BandwidthLimitRulesBuilder bwLimitBuilder = new BandwidthLimitRulesBuilder();
setPortBandwidthLimits(db, odlInterfaceRpcService, port,
bwLimitBuilder.setMaxBurstKbps(BigInteger.ZERO)
.setMaxKbps(BigInteger.ZERO).build());
}
}
}
}
}
}
public static void setPortBandwidthLimits(DataBroker db, OdlInterfaceRpcService odlInterfaceRpcService,
Port port, BandwidthLimitRules bwLimit) {
LOG.trace("Setting bandwidth limits {} on Port {}", port, bwLimit);
BigInteger dpId = getDpnForInterface(odlInterfaceRpcService, port.getUuid().getValue());
if (dpId.equals(BigInteger.ZERO)) {
LOG.info("DPN ID for interface {} not found", port.getUuid().getValue());
return;
}
OvsdbBridgeRef bridgeRefEntry = getBridgeRefEntryFromOperDS(dpId, db);
Optional bridgeNode = MDSALUtil.read(LogicalDatastoreType.OPERATIONAL,
bridgeRefEntry.getValue().firstIdentifierOf(Node.class), db);
TerminationPoint tp = getTerminationPoint(bridgeNode.get(), port.getUuid().getValue());
OvsdbTerminationPointAugmentation ovsdbTp = tp.getAugmentation(OvsdbTerminationPointAugmentation.class);
OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
tpAugmentationBuilder.setName(ovsdbTp.getName());
tpAugmentationBuilder.setIngressPolicingRate(bwLimit.getMaxKbps().longValue());
tpAugmentationBuilder.setIngressPolicingBurst(bwLimit.getMaxBurstKbps().longValue());
TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
tpBuilder.setKey(tp.getKey());
tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
MDSALUtil.syncUpdate(db, LogicalDatastoreType.CONFIGURATION, InstanceIdentifier
.create(NetworkTopology.class)
.child(Topology.class, new TopologyKey(SouthboundUtils.OVSDB_TOPOLOGY_ID))
.child(Node.class, bridgeNode.get().getKey())
.child(TerminationPoint.class, new TerminationPointKey(tp.getKey())), tpBuilder.build());
}
private static TerminationPoint getTerminationPoint(Node bridgeNode, String interfaceName) {
for (TerminationPoint tp : bridgeNode.getTerminationPoint()) {
Boolean found = false;
OvsdbTerminationPointAugmentation ovsdbTp = tp.getAugmentation(OvsdbTerminationPointAugmentation.class);
if (ovsdbTp.getInterfaceExternalIds() != null
&& !ovsdbTp.getInterfaceExternalIds().isEmpty()) {
for (InterfaceExternalIds entry : ovsdbTp.getInterfaceExternalIds()) {
if (entry.getExternalIdKey().equals(EXTERNAL_ID_INTERFACE_ID)
&& entry.getExternalIdValue().equals(interfaceName)) {
found = true;
continue;
}
}
}
if (found) {
return tp;
}
}
return null;
}
private static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
BigInteger nodeId = BigInteger.ZERO;
try {
GetDpidFromInterfaceInput
dpIdInput = new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
Future>
dpIdOutput = interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
RpcResult dpIdResult = dpIdOutput.get();
if (dpIdResult.isSuccessful()) {
nodeId = dpIdResult.getResult().getDpid();
} else {
LOG.error("Could not retrieve DPN Id for interface {}", ifName);
}
} catch (NullPointerException | InterruptedException | ExecutionException e) {
LOG.error("Exception when getting dpn for interface {}", ifName, e);
}
return nodeId;
}
private static BridgeEntry getBridgeEntryFromConfigDS(BigInteger dpnId,
DataBroker dataBroker) {
BridgeEntryKey bridgeEntryKey = new BridgeEntryKey(dpnId);
InstanceIdentifier bridgeEntryInstanceIdentifier = getBridgeEntryIdentifier(bridgeEntryKey);
LOG.debug("Trying to retrieve bridge entry from config for Id: {}", bridgeEntryInstanceIdentifier);
return getBridgeEntryFromConfigDS(bridgeEntryInstanceIdentifier,
dataBroker);
}
private static BridgeEntry getBridgeEntryFromConfigDS(InstanceIdentifier bridgeEntryInstanceIdentifier,
DataBroker dataBroker) {
Optional bridgeEntryOptional =
read(LogicalDatastoreType.CONFIGURATION, bridgeEntryInstanceIdentifier, dataBroker);
if (!bridgeEntryOptional.isPresent()) {
return null;
}
return bridgeEntryOptional.get();
}
private static BridgeRefEntry getBridgeRefEntryFromOperDS(InstanceIdentifier dpnBridgeEntryIid,
DataBroker dataBroker) {
Optional bridgeRefEntryOptional =
read(LogicalDatastoreType.OPERATIONAL, dpnBridgeEntryIid, dataBroker);
if (!bridgeRefEntryOptional.isPresent()) {
return null;
}
return bridgeRefEntryOptional.get();
}
private static OvsdbBridgeRef getBridgeRefEntryFromOperDS(BigInteger dpId,
DataBroker dataBroker) {
BridgeRefEntryKey bridgeRefEntryKey = new BridgeRefEntryKey(dpId);
InstanceIdentifier bridgeRefEntryIid = getBridgeRefEntryIdentifier(bridgeRefEntryKey);
BridgeRefEntry bridgeRefEntry = getBridgeRefEntryFromOperDS(bridgeRefEntryIid, dataBroker);
if (bridgeRefEntry == null) {
// bridge ref entry will be null if the bridge is disconnected from controller.
// In that case, fetch bridge reference from bridge interface entry config DS
BridgeEntry bridgeEntry = getBridgeEntryFromConfigDS(dpId, dataBroker);
if (bridgeEntry == null) {
return null;
}
return bridgeEntry.getBridgeReference();
}
return bridgeRefEntry.getBridgeReference();
}
private static InstanceIdentifier getBridgeRefEntryIdentifier(BridgeRefEntryKey bridgeRefEntryKey) {
InstanceIdentifier.InstanceIdentifierBuilder bridgeRefEntryInstanceIdentifierBuilder =
InstanceIdentifier.builder(BridgeRefInfo.class)
.child(BridgeRefEntry.class, bridgeRefEntryKey);
return bridgeRefEntryInstanceIdentifierBuilder.build();
}
private static InstanceIdentifier getBridgeEntryIdentifier(BridgeEntryKey bridgeEntryKey) {
InstanceIdentifier.InstanceIdentifierBuilder bridgeEntryIdBuilder =
InstanceIdentifier.builder(BridgeInterfaceInfo.class).child(BridgeEntry.class, bridgeEntryKey);
return bridgeEntryIdBuilder.build();
}
private static Optional read(LogicalDatastoreType datastoreType,
InstanceIdentifier path, DataBroker broker) {
ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
Optional result = Optional.absent();
try {
result = tx.read(datastoreType, path).get();
} catch (Exception e) {
throw new RuntimeException(e);
}
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy