2 * Copyright (c) 2017 Intel Corporation and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.netvirt.qosservice;
10 import static java.util.Collections.emptyList;
11 import static org.opendaylight.mdsal.binding.util.Datastore.CONFIGURATION;
13 import com.google.gson.Gson;
14 import com.google.gson.GsonBuilder;
15 import com.google.gson.JsonArray;
16 import com.google.gson.JsonObject;
17 import java.util.ArrayList;
18 import java.util.Collection;
19 import java.util.Collections;
20 import java.util.List;
22 import java.util.Optional;
23 import java.util.concurrent.ConcurrentHashMap;
24 import java.util.concurrent.ConcurrentMap;
25 import java.util.concurrent.CopyOnWriteArraySet;
26 import java.util.concurrent.ExecutionException;
27 import java.util.concurrent.Future;
28 import javax.inject.Inject;
29 import javax.inject.Singleton;
30 import org.apache.felix.service.command.CommandSession;
31 import org.eclipse.jdt.annotation.NonNull;
32 import org.eclipse.jdt.annotation.Nullable;
33 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
34 import org.opendaylight.genius.mdsalutil.ActionInfo;
35 import org.opendaylight.genius.mdsalutil.FlowEntity;
36 import org.opendaylight.genius.mdsalutil.InstructionInfo;
37 import org.opendaylight.genius.mdsalutil.MDSALUtil;
38 import org.opendaylight.genius.mdsalutil.MatchInfo;
39 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
40 import org.opendaylight.genius.mdsalutil.NwConstants;
41 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
42 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldDscp;
43 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
44 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
45 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
46 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
47 import org.opendaylight.genius.utils.ServiceIndex;
48 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
49 import org.opendaylight.mdsal.binding.api.DataBroker;
50 import org.opendaylight.mdsal.binding.util.Datastore.Configuration;
51 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
52 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunnerImpl;
53 import org.opendaylight.mdsal.binding.util.TypedWriteTransaction;
54 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
55 import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager;
56 import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.BridgeInterfaceInfo;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.BridgeRefInfo;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.BridgeEntry;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.BridgeEntryKey;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntry;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntryKey;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceBindings;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeIngress;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceTypeFlowBased;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.StypeOpenflowBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfo;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfoKey;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesKey;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.qos.ext.rev160613.QosNetworkExtension;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.qos.ext.rev160613.QosPortExtension;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.qos.rev160613.qos.attributes.qos.policies.QosPolicy;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.qos.rev160613.qos.attributes.qos.policies.qos.policy.BandwidthLimitRules;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.qos.rev160613.qos.attributes.qos.policies.qos.policy.BandwidthLimitRulesBuilder;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.qos.rev160613.qos.attributes.qos.policies.qos.policy.DscpmarkingRules;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeRef;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
100 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
101 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
102 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
103 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
104 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
105 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
106 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
107 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
108 import org.opendaylight.yangtools.yang.common.RpcResult;
109 import org.opendaylight.yangtools.yang.common.Uint64;
110 import org.slf4j.Logger;
111 import org.slf4j.LoggerFactory;
114 public class QosNeutronUtils {
115 private static final Logger LOG = LoggerFactory.getLogger(QosNeutronUtils.class);
117 private final ConcurrentMap<Uuid, QosPolicy> qosPolicyMap = new ConcurrentHashMap<>();
118 private final ConcurrentMap<Uuid, ConcurrentMap<Uuid, Port>> qosPortsMap = new ConcurrentHashMap<>();
119 private final ConcurrentMap<Uuid, ConcurrentMap<Uuid, Network>> qosNetworksMap = new ConcurrentHashMap<>();
120 private final CopyOnWriteArraySet<Uuid> qosServiceConfiguredPorts = new CopyOnWriteArraySet<>();
121 private final ConcurrentHashMap<Uuid, Port> neutronPortMap = new ConcurrentHashMap<>();
122 private final ConcurrentHashMap<Uuid, Network> neutronNetworkMap = new ConcurrentHashMap<>();
124 private final QosEosHandler qosEosHandler;
125 private final INeutronVpnManager neutronVpnManager;
126 private final OdlInterfaceRpcService odlInterfaceRpcService;
127 private final DataBroker dataBroker;
128 private final ManagedNewTransactionRunner txRunner;
129 private final IMdsalApiManager mdsalUtils;
130 private final JobCoordinator jobCoordinator;
133 public QosNeutronUtils(final QosEosHandler qosEosHandler, final INeutronVpnManager neutronVpnManager,
134 final OdlInterfaceRpcService odlInterfaceRpcService, final DataBroker dataBroker,
135 final IMdsalApiManager mdsalUtils, final JobCoordinator jobCoordinator) {
136 this.qosEosHandler = qosEosHandler;
137 this.neutronVpnManager = neutronVpnManager;
138 this.odlInterfaceRpcService = odlInterfaceRpcService;
139 this.dataBroker = dataBroker;
140 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
141 this.mdsalUtils = mdsalUtils;
142 this.jobCoordinator = jobCoordinator;
145 public void addToQosPolicyCache(QosPolicy qosPolicy) {
146 qosPolicyMap.put(qosPolicy.getUuid(),qosPolicy);
149 public void removeFromQosPolicyCache(QosPolicy qosPolicy) {
150 qosPolicyMap.remove(qosPolicy.getUuid());
153 public Map<Uuid, QosPolicy> getQosPolicyMap() {
157 public Collection<Port> getQosPorts(Uuid qosUuid) {
158 final ConcurrentMap<Uuid, Port> portMap = qosPortsMap.get(qosUuid);
159 return portMap != null ? portMap.values() : emptyList();
162 public void addToQosPortsCache(Uuid qosUuid, Port port) {
163 qosPortsMap.computeIfAbsent(qosUuid, key -> new ConcurrentHashMap<>()).putIfAbsent(port.getUuid(), port);
166 public void removeFromQosPortsCache(Uuid qosUuid, Port port) {
167 if (qosPortsMap.containsKey(qosUuid) && qosPortsMap.get(qosUuid).containsKey(port.getUuid())) {
168 qosPortsMap.get(qosUuid).remove(port.getUuid(), port);
172 public void addToQosNetworksCache(Uuid qosUuid, Network network) {
173 qosNetworksMap.computeIfAbsent(qosUuid, key -> new ConcurrentHashMap<>()).putIfAbsent(network.getUuid(),
177 public void removeFromQosNetworksCache(Uuid qosUuid, Network network) {
178 if (qosNetworksMap.containsKey(qosUuid) && qosNetworksMap.get(qosUuid).containsKey(network.getUuid())) {
179 qosNetworksMap.get(qosUuid).remove(network.getUuid(), network);
183 public void displayConfig(CommandSession session) {
185 session.getConsole().println("QosClusterOwner: " + qosEosHandler.isQosClusterOwner());
186 Gson gson = new GsonBuilder().setPrettyPrinting().create();
188 if (qosPolicyMap.isEmpty() && qosPortsMap.isEmpty() && qosNetworksMap.isEmpty()) {
189 session.getConsole().println("No cache found");
192 if (!qosPolicyMap.isEmpty()) {
193 displayQosPolicyMap(session, gson);
195 if (!qosPortsMap.isEmpty()) {
196 displayQosPortsMap(session, gson);
198 if (!qosNetworksMap.isEmpty()) {
199 displayQosNetworksMap(session, gson);
203 private void displayQosPolicyMap(CommandSession session, Gson gson) {
204 session.getConsole().println("\nQOS Policy Map");
209 String bandwidthUuid;
215 JsonObject jsonObject;
216 JsonArray jsonArray = new JsonArray();
217 for (ConcurrentMap.Entry<Uuid, QosPolicy> policyEntry : qosPolicyMap.entrySet()) {
218 jsonObject = new JsonObject();
220 bandwidthUuid = "null";
224 policyUuid = policyEntry.getKey();
225 uuid = policyEntry.getKey().getValue();
226 policyName = qosPolicyMap.get(policyUuid).getName();
228 if (qosPolicyMap.get(policyUuid).getBandwidthLimitRules() != null) {
229 BandwidthLimitRules bandwidthLimitRules =
230 qosPolicyMap.get(policyUuid).getBandwidthLimitRules().values().iterator().next();
231 if (bandwidthLimitRules.getUuid() != null) {
232 bandwidthUuid = bandwidthLimitRules.getUuid().getValue();
234 if (bandwidthLimitRules.getMaxKbps() != null) {
235 maxRate = bandwidthLimitRules.getMaxKbps().longValue();
237 if (bandwidthLimitRules.getMaxBurstKbps() != null) {
238 maxBurstRate = bandwidthLimitRules.getMaxBurstKbps().longValue();
241 if (qosPolicyMap.get(policyUuid).getDscpmarkingRules() != null) {
242 DscpmarkingRules dscp = qosPolicyMap.get(policyUuid).getDscpmarkingRules().values().iterator().next();
243 if (dscp.getUuid() != null) {
244 dscpUuid = dscp.getUuid().getValue();
246 if (dscp.getDscpMark() != null) {
247 dscpValue = dscp.getDscpMark().toString();
250 jsonObject.addProperty("Policy Uuid", uuid);
251 jsonObject.addProperty("Policy Name", policyName);
252 jsonObject.addProperty("Bandwidth Uuid", bandwidthUuid);
253 jsonObject.addProperty("max kbps", maxRate);
254 jsonObject.addProperty("max burst kbps", maxBurstRate);
255 jsonObject.addProperty("Dscp Uuid", dscpUuid);
256 jsonObject.addProperty("Dscp Value", dscpValue);
257 jsonArray.add(jsonObject);
259 session.getConsole().println(gson.toJson(jsonArray));
262 private void displayQosPortsMap(CommandSession session, Gson gson) {
263 session.getConsole().println("\nQOS Ports Map");
273 JsonObject jsonObject;
274 JsonArray jsonArrayOuter = new JsonArray();
276 for (ConcurrentMap.Entry<Uuid, ConcurrentMap<Uuid, Port>> policyEntry : qosPortsMap.entrySet()) {
277 policyUuid = policyEntry.getKey();
278 policyId = policyUuid.getValue();
279 policyName = qosPolicyMap.get(policyUuid).getName();
280 jsonObject = new JsonObject();
281 jsonArray = new JsonArray();
282 jsonObject.addProperty("Policy Uuid", policyId);
283 jsonObject.addProperty("Policy Name", policyName);
284 ConcurrentMap<Uuid, Port> portInnerMap = qosPortsMap.get(policyUuid);
285 for (ConcurrentMap.Entry<Uuid, Port> portEntry : portInnerMap.entrySet()) {
286 portId = portEntry.getKey();
287 if (portId != null) {
288 portUuid = portInnerMap.get(portId).getUuid().getValue();
289 portName = portInnerMap.get(portId).getName();
290 if (portName == null) {
293 portDetails = portUuid + " : " + portName;
294 jsonArray.add(portDetails);
297 jsonObject.add("Port Details", jsonArray);
298 jsonArrayOuter.add(jsonObject);
300 session.getConsole().println(gson.toJson(jsonArrayOuter));
303 private void displayQosNetworksMap(CommandSession session, Gson gson) {
304 session.getConsole().println("\nQos Networks Map");
310 String networkDetails;
314 JsonObject jsonObject;
315 JsonArray jsonArrayOuter = new JsonArray();
317 for (ConcurrentMap.Entry<Uuid, ConcurrentMap<Uuid, Network>> policyEntry: qosNetworksMap.entrySet()) {
318 policyUuid = policyEntry.getKey();
319 policyId = policyUuid.getValue();
320 policyName = qosPolicyMap.get(policyUuid).getName();
321 jsonObject = new JsonObject();
322 jsonArray = new JsonArray();
323 jsonObject.addProperty("Policy Uuid", policyId);
324 jsonObject.addProperty("Policy Name", policyName);
325 ConcurrentMap<Uuid, Network> networkInnerMap = qosNetworksMap.get(policyUuid);
327 for (ConcurrentMap.Entry<Uuid, Network> networkEntry : networkInnerMap.entrySet()) {
328 networkUuid = networkEntry.getKey();
329 if (networkUuid != null) {
330 networkId = networkInnerMap.get(networkUuid).getUuid().getValue();
331 networkName = networkInnerMap.get(networkUuid).getName();
332 if (networkName == null) {
333 networkName = "null";
335 networkDetails = networkId + " : " + networkName;
336 jsonArray.add(networkDetails);
339 jsonObject.add("Network Details", jsonArray);
340 jsonArrayOuter.add(jsonObject);
343 session.getConsole().println(gson.toJson(jsonArrayOuter));
347 public Collection<Network> getQosNetworks(Uuid qosUuid) {
348 final ConcurrentMap<Uuid, Network> networkMap = qosNetworksMap.get(qosUuid);
349 return networkMap != null ? networkMap.values() : emptyList();
353 public List<Uuid> getSubnetIdsFromNetworkId(Uuid networkId) {
354 InstanceIdentifier<NetworkMap> networkMapId = InstanceIdentifier.builder(NetworkMaps.class)
355 .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
356 Optional<NetworkMap> optionalNetworkMap = MDSALUtil.read(LogicalDatastoreType.CONFIGURATION,
357 networkMapId, dataBroker);
358 return optionalNetworkMap.isPresent() && optionalNetworkMap.get().getSubnetIdList() != null
359 ? optionalNetworkMap.get().getSubnetIdList() : emptyList();
363 protected List<Uuid> getPortIdsFromSubnetId(Uuid subnetId) {
364 InstanceIdentifier<Subnetmap> subnetMapId = InstanceIdentifier
365 .builder(Subnetmaps.class)
366 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
367 Optional<Subnetmap> optionalSubnetmap = MDSALUtil.read(LogicalDatastoreType.CONFIGURATION,
368 subnetMapId,dataBroker);
369 return optionalSubnetmap.isPresent() && optionalSubnetmap.get().getPortList() != null
370 ? optionalSubnetmap.get().getPortList() : emptyList();
373 public void handleNeutronPortQosAdd(Port port, Uuid qosUuid) {
374 LOG.debug("Handling Port add and QoS associated: port: {} qos: {}", port.getUuid().getValue(),
377 QosPolicy qosPolicy = qosPolicyMap.get(qosUuid);
379 jobCoordinator.enqueueJob("QosPort-" + port.getUuid().getValue(),
380 () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
381 // handle Bandwidth Limit Rules update
382 if (qosPolicy != null && qosPolicy.getBandwidthLimitRules() != null
383 && !qosPolicy.getBandwidthLimitRules().isEmpty()) {
384 setPortBandwidthLimits(port, qosPolicy.getBandwidthLimitRules().get(0), tx);
386 // handle DSCP Mark Rules update
387 if (qosPolicy != null && qosPolicy.getDscpmarkingRules() != null
388 && !qosPolicy.getDscpmarkingRules().isEmpty()) {
389 setPortDscpMarking(port, qosPolicy.getDscpmarkingRules().get(0));
394 public void handleQosInterfaceAdd(Port port, Uuid qosUuid) {
395 LOG.debug("Handling Port add and QoS associated: port: {} qos: {}", port.getUuid().getValue(),
398 QosPolicy qosPolicy = qosPolicyMap.get(qosUuid);
400 jobCoordinator.enqueueJob("QosPort-" + port.getUuid().getValue(), () -> {
401 // handle DSCP Mark Rules update
402 if (qosPolicy != null && qosPolicy.getDscpmarkingRules() != null
403 && !qosPolicy.getDscpmarkingRules().isEmpty()) {
404 setPortDscpMarking(port, qosPolicy.getDscpmarkingRules().get(0));
410 public void handleNeutronPortQosUpdate(Port port, Uuid qosUuidNew, Uuid qosUuidOld) {
411 LOG.debug("Handling Port QoS update: port: {} qosservice: {}", port.getUuid().getValue(),
412 qosUuidNew.getValue());
414 QosPolicy qosPolicyNew = qosPolicyMap.get(qosUuidNew);
415 QosPolicy qosPolicyOld = qosPolicyMap.get(qosUuidOld);
417 jobCoordinator.enqueueJob("QosPort-" + port.getUuid().getValue(),
418 () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
419 // handle Bandwidth Limit Rules update
420 if (qosPolicyNew != null && qosPolicyNew.getBandwidthLimitRules() != null
421 && !qosPolicyNew.getBandwidthLimitRules().isEmpty()) {
422 setPortBandwidthLimits(port, qosPolicyNew.getBandwidthLimitRules().get(0), tx);
424 if (qosPolicyOld != null && qosPolicyOld.getBandwidthLimitRules() != null
425 && !qosPolicyOld.getBandwidthLimitRules().isEmpty()) {
426 BandwidthLimitRulesBuilder bwLimitBuilder = new BandwidthLimitRulesBuilder();
427 setPortBandwidthLimits(port, bwLimitBuilder
428 .setMaxBurstKbps(Uint64.ZERO)
429 .setMaxKbps(Uint64.ZERO).build(), tx);
432 //handle DSCP Mark Rules update
433 if (qosPolicyNew != null && qosPolicyNew.getDscpmarkingRules() != null
434 && !qosPolicyNew.getDscpmarkingRules().isEmpty()) {
435 setPortDscpMarking(port, qosPolicyNew.getDscpmarkingRules().get(0));
437 if (qosPolicyOld != null && qosPolicyOld.getDscpmarkingRules() != null
438 && !qosPolicyOld.getDscpmarkingRules().isEmpty()) {
439 unsetPortDscpMark(port);
445 public void handleNeutronPortQosRemove(Port port, Uuid qosUuid) {
446 LOG.debug("Handling Port QoS removal: port: {} qosservice: {}", port.getUuid().getValue(), qosUuid.getValue());
448 // check for network qosservice to apply
449 Network network = neutronVpnManager.getNeutronNetwork(port.getNetworkId());
450 if (network != null && network.augmentation(QosNetworkExtension.class) != null) {
451 Uuid networkQosUuid = network.augmentation(QosNetworkExtension.class).getQosPolicyId();
452 if (networkQosUuid != null) {
453 handleNeutronPortQosUpdate(port, networkQosUuid, qosUuid);
456 QosPolicy qosPolicy = qosPolicyMap.get(qosUuid);
458 jobCoordinator.enqueueJob("QosPort-" + port.getUuid().getValue(),
459 () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
460 // handle Bandwidth Limit Rules removal
461 if (qosPolicy != null && qosPolicy.getBandwidthLimitRules() != null
462 && !qosPolicy.getBandwidthLimitRules().isEmpty()) {
463 BandwidthLimitRulesBuilder bwLimitBuilder = new BandwidthLimitRulesBuilder();
464 setPortBandwidthLimits(port, bwLimitBuilder
465 .setMaxBurstKbps(Uint64.ZERO)
466 .setMaxKbps(Uint64.ZERO).build(), tx);
468 // handle DSCP MArk Rules removal
469 if (qosPolicy != null && qosPolicy.getDscpmarkingRules() != null
470 && !qosPolicy.getDscpmarkingRules().isEmpty()) {
471 unsetPortDscpMark(port);
477 public void handleNeutronPortRemove(Port port, Uuid qosUuid) {
478 LOG.debug("Handling Port removal and Qos associated: port: {} qos: {}", port.getUuid().getValue(),
480 QosPolicy qosPolicy = qosPolicyMap.get(qosUuid);
482 jobCoordinator.enqueueJob("QosPort-" + port.getUuid().getValue(), () -> {
483 //check if any DSCP rule in the policy
484 if (qosPolicy != null && qosPolicy.getDscpmarkingRules() != null
485 && !qosPolicy.getDscpmarkingRules().isEmpty()) {
486 unsetPortDscpMark(port);
492 public void handleNeutronPortRemove(Port port, Uuid qosUuid, Interface intrf) {
493 LOG.debug("Handling Port removal and Qos associated: port: {} qos: {}", port.getUuid().getValue(),
495 QosPolicy qosPolicy = qosPolicyMap.get(qosUuid);
497 jobCoordinator.enqueueJob("QosPort-" + port.getUuid().getValue(), () -> {
498 if (qosPolicy != null && qosPolicy.getDscpmarkingRules() != null
499 && !qosPolicy.getDscpmarkingRules().isEmpty()) {
500 unsetPortDscpMark(port, intrf);
507 public void handleNeutronNetworkQosUpdate(Network network, Uuid qosUuid) {
508 LOG.debug("Handling Network QoS update: net: {} qosservice: {}", network.getUuid().getValue(), qosUuid);
509 QosPolicy qosPolicy = qosPolicyMap.get(qosUuid);
510 if (qosPolicy == null || (qosPolicy.getBandwidthLimitRules() == null
511 || qosPolicy.getBandwidthLimitRules().isEmpty())
512 && (qosPolicy.getDscpmarkingRules() == null
513 || qosPolicy.getDscpmarkingRules().isEmpty())) {
516 List<Uuid> subnetIds = getSubnetIdsFromNetworkId(network.getUuid());
517 for (Uuid subnetId : subnetIds) {
518 List<Uuid> portIds = getPortIdsFromSubnetId(subnetId);
519 for (Uuid portId : portIds) {
520 Port port = getNeutronPort(portId);
521 if (port != null && (port.augmentation(QosPortExtension.class) == null
522 || port.augmentation(QosPortExtension.class).getQosPolicyId() == null)) {
523 jobCoordinator.enqueueJob("QosPort-" + portId.getValue(),
524 () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
525 CONFIGURATION, tx -> {
526 if (qosPolicy.getBandwidthLimitRules() != null
527 && !qosPolicy.getBandwidthLimitRules().isEmpty()) {
528 setPortBandwidthLimits(port, qosPolicy.getBandwidthLimitRules().get(0), tx);
530 if (qosPolicy.getDscpmarkingRules() != null
531 && !qosPolicy.getDscpmarkingRules().isEmpty()) {
532 setPortDscpMarking(port, qosPolicy.getDscpmarkingRules().get(0));
540 public void handleNeutronNetworkQosRemove(Network network, Uuid qosUuid) {
541 LOG.debug("Handling Network QoS removal: net: {} qosservice: {}", network.getUuid().getValue(),
543 QosPolicy qosPolicy = qosPolicyMap.get(qosUuid);
545 List<Uuid> subnetIds = getSubnetIdsFromNetworkId(network.getUuid());
546 for (Uuid subnetId : subnetIds) {
547 List<Uuid> portIds = getPortIdsFromSubnetId(subnetId);
548 for (Uuid portId : portIds) {
549 Port port = getNeutronPort(portId);
550 if (port != null && (port.augmentation(QosPortExtension.class) == null
551 || port.augmentation(QosPortExtension.class).getQosPolicyId() == null)) {
552 jobCoordinator.enqueueJob("QosPort-" + portId.getValue(),
553 () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
554 CONFIGURATION, tx -> {
555 if (qosPolicy != null && qosPolicy.getBandwidthLimitRules() != null
556 && !qosPolicy.getBandwidthLimitRules().isEmpty()) {
557 BandwidthLimitRulesBuilder bwLimitBuilder = new BandwidthLimitRulesBuilder();
558 setPortBandwidthLimits(port, bwLimitBuilder
559 .setMaxBurstKbps(Uint64.ZERO)
560 .setMaxKbps(Uint64.ZERO).build(), tx);
562 if (qosPolicy != null && qosPolicy.getDscpmarkingRules() != null
563 && !qosPolicy.getDscpmarkingRules().isEmpty()) {
564 unsetPortDscpMark(port);
572 public void handleNeutronNetworkQosBwRuleRemove(Network network, BandwidthLimitRules zeroBwLimitRule) {
573 LOG.debug("Handling Qos Bandwidth Rule Remove, net: {}", network.getUuid().getValue());
575 List<Uuid> subnetIds = getSubnetIdsFromNetworkId(network.getUuid());
577 for (Uuid subnetId: subnetIds) {
578 List<Uuid> portIds = getPortIdsFromSubnetId(subnetId);
579 for (Uuid portId : portIds) {
580 Port port = getNeutronPort(portId);
581 if (port != null && (port.augmentation(QosPortExtension.class) == null
582 || port.augmentation(QosPortExtension.class).getQosPolicyId() == null)) {
583 jobCoordinator.enqueueJob("QosPort-" + portId.getValue(), () -> Collections.singletonList(
584 txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
585 tx -> setPortBandwidthLimits(port, zeroBwLimitRule, tx))));
591 public void handleNeutronNetworkQosDscpRuleRemove(Network network) {
592 LOG.debug("Handling Qos Dscp Rule Remove, net: {}", network.getUuid().getValue());
594 List<Uuid> subnetIds = getSubnetIdsFromNetworkId(network.getUuid());
596 for (Uuid subnetId: subnetIds) {
597 List<Uuid> portIds = getPortIdsFromSubnetId(subnetId);
598 for (Uuid portId : portIds) {
599 Port port = getNeutronPort(portId);
600 if (port != null && (port.augmentation(QosPortExtension.class) == null
601 || port.augmentation(QosPortExtension.class).getQosPolicyId() == null)) {
602 jobCoordinator.enqueueJob("QosPort-" + portId.getValue(), () -> {
603 unsetPortDscpMark(port);
611 // TODO Clean up the exception handling
612 @SuppressWarnings("checkstyle:IllegalCatch")
613 public void setPortBandwidthLimits(Port port, BandwidthLimitRules bwLimit,
614 TypedWriteTransaction<Configuration> writeConfigTxn) {
615 if (!qosEosHandler.isQosClusterOwner()) {
616 LOG.debug("Not Qos Cluster Owner. Ignoring setting bandwidth limits");
619 Uint64 dpId = getDpnForInterface(port.getUuid().getValue());
620 if (dpId.equals(Uint64.ZERO)) {
621 LOG.info("DPN ID for interface {} not found", port.getUuid().getValue());
625 LOG.trace("Setting bandwidth limits {} on Port {}", port.getUuid().getValue(), bwLimit);
626 OvsdbBridgeRef bridgeRefEntry = getBridgeRefEntryFromOperDS(dpId);
627 Optional<Node> bridgeNode = MDSALUtil.read(LogicalDatastoreType.OPERATIONAL,
628 bridgeRefEntry.getValue().firstIdentifierOf(Node.class), dataBroker);
629 if (!bridgeNode.isPresent()) {
630 LOG.error("bridge not found for dpn {} port {} in operational datastore", dpId, port.getUuid().getValue());
633 LOG.debug("bridgeNode {}", bridgeNode.get().getNodeId().getValue());
635 TerminationPoint tp = SouthboundUtils.getTerminationPointByExternalId(bridgeNode.get(),
636 port.getUuid().getValue());
638 LOG.debug("Skipping setting of bandwidth limit rules for subport {}",
639 port.getUuid().getValue());
642 LOG.debug("tp: {}", tp.getTpId().getValue());
643 OvsdbTerminationPointAugmentation ovsdbTp = tp.augmentation(OvsdbTerminationPointAugmentation.class);
645 OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
646 tpAugmentationBuilder.setName(ovsdbTp.getName());
647 tpAugmentationBuilder.setIngressPolicingRate(bwLimit.getMaxKbps().longValue());
648 tpAugmentationBuilder.setIngressPolicingBurst(bwLimit.getMaxBurstKbps().longValue());
650 TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
651 tpBuilder.withKey(tp.key());
652 tpBuilder.addAugmentation(tpAugmentationBuilder.build());
654 if (writeConfigTxn != null) {
655 writeConfigTxn.mergeParentStructureMerge(InstanceIdentifier
656 .create(NetworkTopology.class)
657 .child(Topology.class, new TopologyKey(SouthboundUtils.OVSDB_TOPOLOGY_ID))
658 .child(Node.class, bridgeNode.get().key())
659 .child(TerminationPoint.class, new TerminationPointKey(tp.key())), tpBuilder.build());
661 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, InstanceIdentifier
662 .create(NetworkTopology.class)
663 .child(Topology.class, new TopologyKey(SouthboundUtils.OVSDB_TOPOLOGY_ID))
664 .child(Node.class, bridgeNode.get().key())
665 .child(TerminationPoint.class, new TerminationPointKey(tp.key())), tpBuilder.build());
667 } catch (Exception e) {
668 if (LOG.isDebugEnabled()) {
669 LOG.debug("Failure while setting BwLimitRule {} to port {} exception ", bwLimit,
670 port.getUuid().getValue(), e);
672 LOG.error("Failure while setting BwLimitRule {} to port {}", bwLimit, port.getUuid().getValue());
678 public void setPortDscpMarking(Port port, DscpmarkingRules dscpMark) {
680 Uint64 dpnId = getDpnForInterface(port.getUuid().getValue());
681 String ifName = port.getUuid().getValue();
683 if (dpnId.equals(Uint64.ZERO)) {
684 LOG.info("DPN ID for interface {} not found. Cannot set dscp value {} on port {}",
685 port.getUuid().getValue(), dscpMark, port.getUuid().getValue());
689 if (!qosEosHandler.isQosClusterOwner()) {
690 qosServiceConfiguredPorts.add(port.getUuid());
691 LOG.trace("Not Qos Cluster Owner. Ignoring setting DSCP marking");
694 Interface ifState = getInterfaceStateFromOperDS(ifName);
695 Short dscpValue = dscpMark.getDscpMark().toJava();
696 int ipVersions = getIpVersions(port);
698 if (hasIpv4Addr(ipVersions)) {
699 LOG.trace("setting ipv4 flow for port: {}, dscp: {}", ifName, dscpValue);
700 addFlow(dpnId, dscpValue, ifName, NwConstants.ETHTYPE_IPV4, ifState);
702 if (hasIpv6Addr(ipVersions)) {
703 LOG.trace("setting ipv6 flow for port: {}, dscp: {}", ifName, dscpValue);
704 addFlow(dpnId, dscpValue, ifName, NwConstants.ETHTYPE_IPV6, ifState);
707 if (qosServiceConfiguredPorts.add(port.getUuid())) {
708 // bind qos service to interface
715 public void unsetPortDscpMark(Port port) {
717 Uint64 dpnId = getDpnForInterface(port.getUuid().getValue());
718 String ifName = port.getUuid().getValue();
720 if (dpnId.equals(Uint64.ZERO)) {
721 LOG.debug("DPN ID for port {} not found. Cannot unset dscp value", port.getUuid().getValue());
725 if (!qosEosHandler.isQosClusterOwner()) {
726 qosServiceConfiguredPorts.remove(port.getUuid());
727 LOG.debug("Not Qos Cluster Owner. Ignoring unsetting DSCP marking");
730 LOG.trace("Removing dscp marking rule from Port {}", port.getUuid().getValue());
731 Interface intf = getInterfaceStateFromOperDS(ifName);
732 //unbind service from interface
733 unbindservice(ifName);
735 int ipVersions = getIpVersions(port);
736 if (hasIpv4Addr(ipVersions)) {
737 removeFlow(dpnId, ifName, NwConstants.ETHTYPE_IPV4, intf);
739 if (hasIpv6Addr(ipVersions)) {
740 removeFlow(dpnId, ifName, NwConstants.ETHTYPE_IPV6, intf);
742 qosServiceConfiguredPorts.remove(port.getUuid());
746 public void unsetPortDscpMark(Port port, Interface intrf) {
748 Uint64 dpnId = getDpIdFromInterface(intrf);
749 String ifName = port.getUuid().getValue();
751 if (dpnId.equals(Uint64.ZERO)) {
752 LOG.error("Unable to retrieve DPN Id for interface {}. Cannot unset dscp value on port", ifName);
755 if (!qosEosHandler.isQosClusterOwner()) {
756 qosServiceConfiguredPorts.remove(port.getUuid());
759 LOG.trace("Removing dscp marking rule from Port {}", port.getUuid().getValue());
760 unbindservice(ifName);
761 int ipVersions = getIpVersions(port);
762 if (hasIpv4Addr(ipVersions)) {
763 removeFlow(dpnId, ifName, NwConstants.ETHTYPE_IPV4, intrf);
765 if (hasIpv6Addr(ipVersions)) {
766 removeFlow(dpnId, ifName, NwConstants.ETHTYPE_IPV6, intrf);
768 qosServiceConfiguredPorts.remove(port.getUuid());
772 private static Uint64 getDpIdFromInterface(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
773 .interfaces.rev140508.interfaces.state.Interface ifState) {
774 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
775 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
776 Long dpIdLong = MDSALUtil.getDpnIdFromPortName(nodeConnectorId);
777 Uint64 dpnId = dpIdLong < 0 ? Uint64.ZERO : Uint64.valueOf(dpIdLong);
781 public Uint64 getDpnForInterface(String ifName) {
782 Uint64 nodeId = Uint64.ZERO;
784 GetDpidFromInterfaceInput
785 dpIdInput = new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
786 Future<RpcResult<GetDpidFromInterfaceOutput>>
787 dpIdOutput = odlInterfaceRpcService.getDpidFromInterface(dpIdInput);
788 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
789 if (dpIdResult.isSuccessful()) {
790 nodeId = dpIdResult.getResult().getDpid();
792 LOG.error("Could not retrieve DPN Id for interface {}", ifName);
794 } catch (NullPointerException | InterruptedException | ExecutionException e) {
795 if (LOG.isDebugEnabled()) {
796 LOG.debug("Exception when getting DPN for interface {} exception ", ifName, e);
798 LOG.error("Could not retrieve DPN for interface {}", ifName);
805 private BridgeEntry getBridgeEntryFromConfigDS(Uint64 dpnId) {
806 BridgeEntryKey bridgeEntryKey = new BridgeEntryKey(dpnId);
807 InstanceIdentifier<BridgeEntry> bridgeEntryInstanceIdentifier = getBridgeEntryIdentifier(bridgeEntryKey);
808 LOG.debug("Trying to retrieve bridge entry from config for Id: {}", bridgeEntryInstanceIdentifier);
809 return getBridgeEntryFromConfigDS(bridgeEntryInstanceIdentifier);
813 private BridgeEntry getBridgeEntryFromConfigDS(InstanceIdentifier<BridgeEntry> bridgeEntryInstanceIdentifier) {
814 return MDSALUtil.read(LogicalDatastoreType.CONFIGURATION, bridgeEntryInstanceIdentifier, dataBroker)
819 private BridgeRefEntry getBridgeRefEntryFromOperDS(InstanceIdentifier<BridgeRefEntry> dpnBridgeEntryIid) {
820 return MDSALUtil.read(LogicalDatastoreType.OPERATIONAL, dpnBridgeEntryIid, dataBroker).orElse(null);
824 private OvsdbBridgeRef getBridgeRefEntryFromOperDS(Uint64 dpId) {
825 BridgeRefEntryKey bridgeRefEntryKey = new BridgeRefEntryKey(dpId);
826 InstanceIdentifier<BridgeRefEntry> bridgeRefEntryIid = getBridgeRefEntryIdentifier(bridgeRefEntryKey);
827 BridgeRefEntry bridgeRefEntry = getBridgeRefEntryFromOperDS(bridgeRefEntryIid);
828 if (bridgeRefEntry == null) {
829 // bridge ref entry will be null if the bridge is disconnected from controller.
830 // In that case, fetch bridge reference from bridge interface entry config DS
831 BridgeEntry bridgeEntry = getBridgeEntryFromConfigDS(dpId);
832 if (bridgeEntry == null) {
835 return bridgeEntry.getBridgeReference();
837 return bridgeRefEntry.getBridgeReference();
841 private static InstanceIdentifier<BridgeRefEntry> getBridgeRefEntryIdentifier(BridgeRefEntryKey bridgeRefEntryKey) {
842 return InstanceIdentifier.builder(BridgeRefInfo.class).child(BridgeRefEntry.class, bridgeRefEntryKey).build();
846 private static InstanceIdentifier<BridgeEntry> getBridgeEntryIdentifier(BridgeEntryKey bridgeEntryKey) {
847 return InstanceIdentifier.builder(BridgeInterfaceInfo.class).child(BridgeEntry.class, bridgeEntryKey).build();
850 public void removeStaleFlowEntry(Interface intrf, int ethType) {
851 List<MatchInfo> matches = new ArrayList<>();
853 Uint64 dpnId = getDpIdFromInterface(intrf);
855 Integer ifIndex = intrf.getIfIndex();
856 matches.add(new MatchMetadata(MetaDataUtil.getLportTagMetaData(ifIndex), MetaDataUtil.METADATA_MASK_LPORT_TAG));
857 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpnId, NwConstants.QOS_DSCP_TABLE,
858 getQosFlowId(NwConstants.QOS_DSCP_TABLE, dpnId, ifIndex, ethType),
859 QosConstants.QOS_DEFAULT_FLOW_PRIORITY, "QoSRemoveFlow", 0, 0, NwConstants.COOKIE_QOS_TABLE,
861 mdsalUtils.removeFlow(flowEntity);
864 public void addFlow(Uint64 dpnId, Short dscpValue, String ifName, int ethType, Interface ifState) {
865 if (ifState == null) {
866 LOG.debug("Could not find the ifState for interface {}", ifName);
869 Integer ifIndex = ifState.getIfIndex();
871 List<MatchInfo> matches = new ArrayList<>();
872 matches.add(new MatchEthernetType(ethType));
873 matches.add(new MatchMetadata(MetaDataUtil.getLportTagMetaData(ifIndex), MetaDataUtil.METADATA_MASK_LPORT_TAG));
875 List<ActionInfo> actionsInfos = new ArrayList<>();
876 actionsInfos.add(new ActionSetFieldDscp(dscpValue));
877 actionsInfos.add(new ActionNxResubmit(NwConstants.LPORT_DISPATCHER_TABLE));
879 List<InstructionInfo> instructions = Collections.singletonList(new InstructionApplyActions(actionsInfos));
880 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpnId, NwConstants.QOS_DSCP_TABLE,
881 getQosFlowId(NwConstants.QOS_DSCP_TABLE, dpnId, ifIndex, ethType),
882 QosConstants.QOS_DEFAULT_FLOW_PRIORITY, "QoSConfigFlow", 0, 0, NwConstants.COOKIE_QOS_TABLE,
883 matches, instructions);
884 mdsalUtils.installFlow(flowEntity);
887 public void removeFlow(Uint64 dpnId, String ifName, int ethType, Interface ifState) {
888 if (ifState == null) {
889 LOG.debug("Could not find the ifState for interface {}", ifName);
892 Integer ifIndex = ifState.getIfIndex();
894 mdsalUtils.removeFlow(dpnId, NwConstants.QOS_DSCP_TABLE,
895 new FlowId(getQosFlowId(NwConstants.QOS_DSCP_TABLE, dpnId, ifIndex, ethType)));
898 public org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state
899 .@Nullable Interface getInterfaceStateFromOperDS(String interfaceName) {
901 return SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL,
902 createInterfaceStateInstanceIdentifier(interfaceName)).orElse(null);
903 } catch (ExecutionException | InterruptedException e) {
904 LOG.error("getInterfaceStateFromOperDS: Exception while reading interface DS for the interface {}",
911 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
912 .ietf.interfaces.rev140508.interfaces.state.Interface> createInterfaceStateInstanceIdentifier(
913 String interfaceName) {
914 return InstanceIdentifier
915 .builder(InterfacesState.class)
916 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
917 .ietf.interfaces.rev140508.interfaces.state.Interface.class,
918 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
919 .ietf.interfaces.rev140508.interfaces.state.InterfaceKey(
924 public void bindservice(String ifName) {
925 int priority = QosConstants.QOS_DEFAULT_FLOW_PRIORITY;
926 int instructionKey = 0;
927 List<Instruction> instructions = new ArrayList<>();
928 instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(NwConstants.QOS_DSCP_TABLE, ++instructionKey));
929 short qosServiceIndex = ServiceIndex.getIndex(NwConstants.QOS_SERVICE_NAME, NwConstants.QOS_SERVICE_INDEX);
931 BoundServices serviceInfo = getBoundServices(
932 String.format("%s.%s", "qos", ifName), qosServiceIndex,
933 priority, NwConstants.COOKIE_QOS_TABLE, instructions);
934 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
935 buildServiceId(ifName, qosServiceIndex),
939 public void unbindservice(String ifName) {
940 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, buildServiceId(ifName,
941 ServiceIndex.getIndex(NwConstants.QOS_SERVICE_NAME, NwConstants.QOS_SERVICE_INDEX)));
944 private static InstanceIdentifier<BoundServices> buildServiceId(String interfaceName, short qosServiceIndex) {
945 return InstanceIdentifier.builder(ServiceBindings.class)
946 .child(ServicesInfo.class, new ServicesInfoKey(interfaceName, ServiceModeIngress.class))
947 .child(BoundServices.class, new BoundServicesKey(qosServiceIndex)).build();
950 private static BoundServices getBoundServices(String serviceName, short qosServiceIndex, int priority,
951 Uint64 cookieQosTable, List<Instruction> instructions) {
952 StypeOpenflowBuilder augBuilder = new StypeOpenflowBuilder().setFlowCookie(cookieQosTable)
953 .setFlowPriority(priority).setInstruction(instructions);
954 return new BoundServicesBuilder().withKey(new BoundServicesKey(qosServiceIndex)).setServiceName(serviceName)
955 .setServicePriority(qosServiceIndex).setServiceType(ServiceTypeFlowBased.class)
956 .addAugmentation(augBuilder.build()).build();
960 public static String getQosFlowId(short tableId, Uint64 dpId, int lportTag, int ethType) {
961 return new StringBuilder().append(tableId).append(NwConstants.FLOWID_SEPARATOR).append(dpId)
962 .append(NwConstants.FLOWID_SEPARATOR).append(lportTag)
963 .append(NwConstants.FLOWID_SEPARATOR).append(ethType).toString();
966 public boolean portHasQosPolicy(Port port) {
967 LOG.trace("checking qos policy for port: {}", port.getUuid().getValue());
969 boolean isQosPolicy = port.augmentation(QosPortExtension.class) != null
970 && port.augmentation(QosPortExtension.class).getQosPolicyId() != null;
972 LOG.trace("portHasQosPolicy for port: {} return value {}", port.getUuid().getValue(), isQosPolicy);
977 public QosPolicy getQosPolicy(Port port) {
979 QosPolicy qosPolicy = null;
981 if (port.augmentation(QosPortExtension.class) != null) {
982 qosUuid = port.augmentation(QosPortExtension.class).getQosPolicyId();
984 Network network = neutronVpnManager.getNeutronNetwork(port.getNetworkId());
986 if (network != null && network.augmentation(QosNetworkExtension.class) != null) {
987 qosUuid = network.augmentation(QosNetworkExtension.class).getQosPolicyId();
991 if (qosUuid != null) {
992 qosPolicy = qosPolicyMap.get(qosUuid);
998 public boolean hasDscpMarkingRule(QosPolicy qosPolicy) {
999 if (qosPolicy != null) {
1000 return qosPolicy.getDscpmarkingRules() != null && !qosPolicy.getDscpmarkingRules().isEmpty();
1005 public void addToPortCache(Port port) {
1006 neutronPortMap.put(port.getUuid(), port);
1009 public void removeFromPortCache(Port port) {
1010 neutronPortMap.remove(port.getUuid());
1013 public Port getNeutronPort(Uuid portUuid) {
1014 return neutronPortMap.get(portUuid);
1017 public Port getNeutronPort(String portName) {
1018 return getNeutronPort(new Uuid(portName));
1021 public void addToNetworkCache(Network network) {
1022 neutronNetworkMap.put(network.getUuid(), network);
1025 public void removeFromNetworkCache(Network network) {
1026 neutronNetworkMap.remove(network.getUuid());
1029 public Network getNeutronNetwork(Uuid networkUuid) {
1030 return neutronNetworkMap.get(networkUuid);
1034 public static Uint64 getDpnIdFromLowerLayerIf(String lowerLayerIf) {
1036 return Uint64.valueOf(lowerLayerIf.substring(lowerLayerIf.indexOf(":") + 1, lowerLayerIf.lastIndexOf(":")));
1037 } catch (NullPointerException e) {
1043 public static String getPortNumberFromLowerLayerIf(String lowerLayerIf) {
1045 return lowerLayerIf.substring(lowerLayerIf.lastIndexOf(":") + 1);
1046 } catch (NullPointerException e) {
1051 public int getIpVersions(Port port) {
1053 for (FixedIps fixedIp: port.nonnullFixedIps().values()) {
1054 if (fixedIp.getIpAddress().getIpv4Address() != null) {
1055 versions |= 1 << QosConstants.IPV4_ADDR_MASK_BIT;
1056 } else if (fixedIp.getIpAddress().getIpv6Address() != null) {
1057 versions |= 1 << QosConstants.IPV6_ADDR_MASK_BIT;
1063 public boolean hasIpv4Addr(int versions) {
1064 return (versions & 1 << QosConstants.IPV4_ADDR_MASK_BIT) != 0;
1067 public boolean hasIpv6Addr(int versions) {
1068 return (versions & 1 << QosConstants.IPV6_ADDR_MASK_BIT) != 0;
1071 public boolean isBindServiceDone(Optional<Uuid> uuid) {
1073 return qosServiceConfiguredPorts.contains(uuid.get());
1078 public void removeInterfaceInQosConfiguredPorts(Optional<Uuid> uuid) {
1080 qosServiceConfiguredPorts.remove(uuid.get());