f11ea929e9d972de7fded6005db59c0228cd51b6
[unimgr.git] / netvirt / src / main / java / org / opendaylight / unimgr / mef / netvirt / IpvcListener.java
1 /*
2  * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.unimgr.mef.netvirt;
10
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.List;
14
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
17 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
18 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
21 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.subnets.Subnet;
22 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.subnets.SubnetBuilder;
23 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.ip.unis.IpUni;
24 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.IpvcVpn;
25 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.Ipvc;
26 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.ipvc.VpnElans;
27 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.ipvc.unis.Uni;
28 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.Identifier45;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface.EtreeInterfaceType;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance;
38 import org.opendaylight.yangtools.concepts.ListenerRegistration;
39 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> {
44     private static final Logger Log = LoggerFactory.getLogger(IpvcListener.class);
45     private final IUniPortManager uniPortManager;
46     private final ISubnetManager subnetManager;
47     private final UniQosManager uniQosManager;
48     private ListenerRegistration<IpvcListener> ipvcListenerRegistration;
49
50     public IpvcListener(final DataBroker dataBroker, final IUniPortManager uniPortManager,
51             final ISubnetManager subnetManager, final UniQosManager uniQosManager) {
52         super(dataBroker);
53         this.uniPortManager = uniPortManager;
54         this.subnetManager = subnetManager;
55         this.uniQosManager = uniQosManager;
56         registerListener();
57     }
58
59     public void registerListener() {
60         try {
61             final DataTreeIdentifier<Ipvc> dataTreeIid = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
62                     MefServicesUtils.getIpvcsInstanceIdentifier());
63             ipvcListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
64             Log.info("IpvcDataTreeChangeListener created and registered");
65         } catch (final Exception e) {
66             Log.error("Ipvc DataChange listener registration failed !", e);
67             throw new IllegalStateException("Ipvc registration Listener failed.", e);
68         }
69     }
70
71     @Override
72     public void close() throws Exception {
73         ipvcListenerRegistration.close();
74     }
75
76     @Override
77     public void add(DataTreeModification<Ipvc> newDataObject) {
78         if (newDataObject.getRootPath() != null && newDataObject.getRootNode() != null) {
79             Log.info("ipvc {} created", newDataObject.getRootNode().getIdentifier());
80             addIpvc(newDataObject);
81         }
82     }
83
84     @Override
85     public void remove(DataTreeModification<Ipvc> removedDataObject) {
86         if (removedDataObject.getRootPath() != null && removedDataObject.getRootNode() != null) {
87             Log.info("ipvc {} deleted", removedDataObject.getRootNode().getIdentifier());
88             removeIpvc(removedDataObject);
89         }
90     }
91
92     @Override
93     public void update(DataTreeModification<Ipvc> modifiedDataObject) {
94         if (modifiedDataObject.getRootPath() != null && modifiedDataObject.getRootNode() != null) {
95             Log.info("ipvc {} updated", modifiedDataObject.getRootNode().getIdentifier());
96             updateIpvc(modifiedDataObject);
97         }
98     }
99
100     private void addIpvc(DataTreeModification<Ipvc> newDataObject) {
101         try {
102             Ipvc ipvc = newDataObject.getRootNode().getDataAfter();
103             String instanceName = ipvc.getIpvcId().getValue();
104             final String vpnName = NetvirtVpnUtils.getUUidFromString(instanceName);
105             InstanceIdentifier<Ipvc> ipvcId = newDataObject.getRootPath().getRootIdentifier();
106             List<Uni> unis = new ArrayList<>();
107             String rd = null;
108             synchronized (vpnName.intern()) {
109                 WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
110                 Log.info("Adding vpn instance: " + instanceName);
111                 NetvirtVpnUtils.createVpnInstance(vpnName, tx);
112                 MefServicesUtils.addOperIpvcVpnElan(ipvcId, vpnName, tx);
113                 MdsalUtils.commitTransaction(tx);
114
115                 InstanceIdentifier<VpnInstance> vpnId = NetvirtVpnUtils.getVpnInstanceToVpnIdIdentifier(vpnName);
116                 DataWaitListener<VpnInstance> vpnInstanceWaiter = new DataWaitListener<>(dataBroker, vpnId, 10,
117                         LogicalDatastoreType.CONFIGURATION, vpn -> vpn.getVrfId());
118                 if (!vpnInstanceWaiter.waitForData()) {
119                     String errorMessage = String.format("Fail to wait for vrfId for vpn %s", vpnName);
120                     Log.error(errorMessage);
121                     throw new UnsupportedOperationException(errorMessage);
122                 }
123                 rd = (String) vpnInstanceWaiter.getData();
124             }
125
126             if (ipvc.getUnis() != null && ipvc.getUnis() != null) {
127                 unis = ipvc.getUnis().getUni();
128             }
129             Log.info("Number of UNI's: " + unis.size());
130
131             // Create elan/vpn interfaces
132             for (Uni uni : unis) {
133                 createInterfaces(vpnName, uni, ipvcId, rd);
134             }
135
136             createUnis(ipvcId, unis);
137         } catch (final Exception e) {
138             Log.error("Add ipvc failed !", e);
139         }
140     }
141
142     private void removeIpvc(DataTreeModification<Ipvc> removedDataObject) {
143         try {
144             Ipvc ipvc = removedDataObject.getRootNode().getDataBefore();
145             InstanceIdentifier<Ipvc> ipvcId = removedDataObject.getRootPath().getRootIdentifier();
146             IpvcVpn operIpvcVpn = MefServicesUtils.getOperIpvcVpn(dataBroker, ipvcId);
147             if (operIpvcVpn == null) {
148                 Log.error("Ipvc {} hasn't been created as required", ipvc.getIpvcId());
149                 return;
150             }
151             String vpnName = operIpvcVpn.getVpnId();
152
153             synchronized (vpnName.intern()) {
154                 // remove elan/vpn interfaces
155                 // must be in different transactios
156                 WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
157                 removeUnis(ipvcId, operIpvcVpn, ipvc.getUnis().getUni(), tx);
158                 MdsalUtils.commitTransaction(tx);
159                 // Let to work for listeners
160                 // TODO : change to listener
161                 NetvirtUtils.safeSleep();
162
163                 WriteTransaction txvpn = MdsalUtils.createTransaction(dataBroker);
164                 NetvirtVpnUtils.removeVpnInstance(operIpvcVpn.getVpnId(), txvpn);
165                 MefServicesUtils.removeOperIpvcVpn(ipvcId, txvpn);
166                 MdsalUtils.commitTransaction(txvpn);
167             }
168         } catch (final Exception e) {
169             Log.error("Remove ipvc failed !", e);
170         }
171     }
172
173     private void removeUnis(InstanceIdentifier<Ipvc> ipvcId, IpvcVpn operIpvcVpn, List<Uni> uniToRemove,
174             WriteTransaction tx) {
175         if (uniToRemove == null) {
176             Log.trace("No UNI's to remove");
177         }
178         for (Uni uni : uniToRemove) {
179             Identifier45 uniId = uni.getUniId();
180             Identifier45 ipUniId = uni.getIpUniId();
181             IpUni ipUni = MefInterfaceUtils.getIpUni(dataBroker, uniId, ipUniId, LogicalDatastoreType.CONFIGURATION);
182             if (ipUni == null) {
183                 String errorMessage = String.format("Couldn't find ipuni %s for uni %s", ipUniId, uniId);
184                 Log.error(errorMessage);
185                 throw new UnsupportedOperationException(errorMessage);
186             }
187
188             removeDirectSubnet(uni, ipUni);
189             subnetManager.unAssignIpUniNetworks(uni.getUniId(), ipUni.getIpUniId(), ipvcId);
190             removeInterfaces(ipvcId, operIpvcVpn, uni, ipUni, tx);
191         }
192         updateQos(uniToRemove);
193     }
194
195     private void createUnis(InstanceIdentifier<Ipvc> ipvcId, List<Uni> uniToCreate) {
196         for (Uni uni : uniToCreate) {
197             IpUni ipUni = MefInterfaceUtils.getIpUni(dataBroker, uni.getUniId(), uni.getIpUniId(),
198                     LogicalDatastoreType.CONFIGURATION);
199             createDirectSubnet(uni, ipUni);
200             subnetManager.assignIpUniNetworks(uni.getUniId(), ipUni.getIpUniId(), ipvcId);
201         }
202         updateQos(uniToCreate);
203     }
204
205     private void updateIpvc(DataTreeModification<Ipvc> modifiedDataObject) {
206         try {
207             Ipvc origIpvc = modifiedDataObject.getRootNode().getDataBefore();
208             Ipvc updateIpvc = modifiedDataObject.getRootNode().getDataAfter();
209             InstanceIdentifier<Ipvc> ipvcId = modifiedDataObject.getRootPath().getRootIdentifier();
210             IpvcVpn operIpvcVpn = MefServicesUtils.getOperIpvcVpn(dataBroker, ipvcId);
211             if (operIpvcVpn == null) {
212                 Log.error("Ipvc {} hasn't been created as required", origIpvc.getIpvcId());
213                 return;
214             }
215             String vpnName = operIpvcVpn.getVpnId();
216             InstanceIdentifier<VpnInstance> vpnId = NetvirtVpnUtils.getVpnInstanceToVpnIdIdentifier(vpnName);
217             @SuppressWarnings("resource")
218             DataWaitListener<VpnInstance> vpnInstanceWaiter = new DataWaitListener<>(dataBroker, vpnId, 10,
219                     LogicalDatastoreType.CONFIGURATION, vpn -> vpn.getVrfId());
220             if (!vpnInstanceWaiter.waitForData()) {
221                 String errorMessage = String.format("Fail to wait for vrfId for vpn %s", vpnName);
222                 Log.error(errorMessage);
223                 throw new UnsupportedOperationException(errorMessage);
224             }
225             String rd = (String) vpnInstanceWaiter.getData();
226
227             List<Uni> originalUni = origIpvc.getUnis() != null && origIpvc.getUnis().getUni() != null
228                     ? origIpvc.getUnis().getUni() : Collections.emptyList();
229             List<Uni> updateUni = updateIpvc.getUnis() != null && updateIpvc.getUnis().getUni() != null
230                     ? updateIpvc.getUnis().getUni() : Collections.emptyList();
231
232             synchronized (vpnName.intern()) {
233                 WriteTransaction txRemove = MdsalUtils.createTransaction(dataBroker);
234                 List<Uni> uniToRemove = new ArrayList<>(originalUni);
235                 uniToRemove.removeAll(updateUni);
236                 removeUnis(ipvcId, operIpvcVpn, uniToRemove, txRemove);
237                 MdsalUtils.commitTransaction(txRemove);
238             }
239             List<Uni> uniToCreate = new ArrayList<>(updateUni);
240             uniToCreate.removeAll(originalUni);
241
242             for (Uni uni : uniToCreate) {
243                 createInterfaces(vpnName, uni, ipvcId, rd);
244             }
245             createUnis(ipvcId, uniToCreate);
246
247         } catch (final Exception e) {
248             Log.error("Update ipvc failed !", e);
249         }
250     }
251
252     private void createInterfaces(String vpnName, Uni uniInService, InstanceIdentifier<Ipvc> ipvcId, String rd) {
253
254         WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
255         String uniId = uniInService.getUniId().getValue();
256         String ipUniId = uniInService.getIpUniId().getValue();
257         org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni uni = MefInterfaceUtils
258                 .getUni(dataBroker, uniId, LogicalDatastoreType.OPERATIONAL);
259         if (uni == null) {
260             String errorMessage = String.format("Couldn't find uni %s for ipvc", uniId);
261             Log.error(errorMessage);
262             throw new UnsupportedOperationException(errorMessage);
263         }
264         IpUni ipUni = MefInterfaceUtils.getIpUni(dataBroker, uniInService.getUniId(), uniInService.getIpUniId(),
265                 LogicalDatastoreType.CONFIGURATION);
266         if (ipUni == null) {
267             String errorMessage = String.format("Couldn't find ipuni %s for uni %s", ipUniId, uniId);
268             Log.error(errorMessage);
269             throw new UnsupportedOperationException(errorMessage);
270         }
271
272         String interfaceName = null;
273         synchronized (vpnName.intern()) {
274             Long vlan = ipUni.getVlan() != null ? Long.valueOf(ipUni.getVlan().getValue()) : null;
275             String elanName = NetvirtVpnUtils.getElanNameForVpnPort(uniId, ipUniId);
276
277             String srcIpAddressStr = NetvirtVpnUtils
278                     .getIpAddressFromPrefix(NetvirtVpnUtils.ipPrefixToString(ipUni.getIpAddress()));
279             IpAddress ipAddress = new IpAddress(srcIpAddressStr.toCharArray());
280
281             interfaceName = createElanInterface(vpnName, ipvcId, uniId, elanName, vlan, ipAddress, tx,
282                     ipUni.getSegmentationId());
283             uniQosManager.mapUniPortBandwidthLimits(uniId, interfaceName, uniInService.getIngressBwProfile());
284             createVpnInterface(vpnName, uni, ipUni, interfaceName, elanName, tx);
285             MefServicesUtils.addOperIpvcVpnElan(ipvcId, vpnName, uniInService.getUniId(), uniInService.getIpUniId(),
286                     elanName, interfaceName, null, tx);
287             MdsalUtils.commitTransaction(tx);
288         }
289
290         waitForInterfaceDpn(vpnName, rd, interfaceName);
291
292         NetvirtVpnUtils.createVpnPortFixedIp(dataBroker, vpnName, interfaceName, ipUni.getIpAddress(),
293                 uni.getMacAddress());
294     }
295
296     private void waitForInterfaceDpn(String vpnName, String rd, String interfaceName) {
297         InstanceIdentifier<VpnInstanceOpDataEntry> vpnId = NetvirtVpnUtils.getVpnInstanceOpDataIdentifier(rd);
298         DataWaitGetter<VpnInstanceOpDataEntry> getInterfByName = (vpn) -> {
299             if (vpn.getVpnToDpnList() == null)
300                 return null;
301             for (VpnToDpnList is : vpn.getVpnToDpnList()) {
302                 if (is.getVpnInterfaces() == null)
303                     continue;
304                 for (VpnInterfaces i : is.getVpnInterfaces()) {
305                     if (i.getInterfaceName().equals(interfaceName))
306                         return interfaceName;
307                 }
308             }
309             return null;
310         };
311         @SuppressWarnings("resource")
312         DataWaitListener<VpnInstanceOpDataEntry> vpnInstanceWaiter = new DataWaitListener<>(dataBroker, vpnId, 10,
313                 LogicalDatastoreType.OPERATIONAL, getInterfByName);
314         if (!vpnInstanceWaiter.waitForData()) {
315             String errorMessage = String.format("Fail to wait for vpn to dpn list %s", vpnName);
316             Log.error(errorMessage);
317             throw new UnsupportedOperationException(errorMessage);
318         }
319     }
320
321     private String createElanInterface(String vpnName, InstanceIdentifier<Ipvc> ipvcId, String uniId, String elanName,
322             Long vlan, IpAddress ipAddress, WriteTransaction tx, Long segmentationId) {
323         Log.info("Adding elan instance: " + elanName);
324         NetvirtUtils.updateElanInstance(elanName, tx, segmentationId);
325         NetvirtVpnUtils.registerDirectSubnetForVpn(dataBroker, new Uuid(elanName), ipAddress);
326
327         Log.info("Added trunk interface for uni {} vlan: {}", uniId, vlan);
328         if (vlan != null) {
329             uniPortManager.addCeVlan(uniId, vlan);
330         }
331         String interfaceName = uniPortManager.getUniVlanInterface(uniId, vlan);
332         if (interfaceName == null) {
333             String errorMessage = String.format("Couldn't create  uni %s vlan interface %s", uniId, vlan);
334             Log.error(errorMessage);
335             throw new UnsupportedOperationException(errorMessage);
336         }
337
338         Log.info("Adding elan interface: " + interfaceName);
339         NetvirtUtils.createElanInterface(elanName, interfaceName, EtreeInterfaceType.Root, false, tx);
340         return interfaceName;
341     }
342
343     private void createVpnInterface(String vpnName,
344             org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni uni,
345             IpUni ipUni, String interfaceName, String elanName, WriteTransaction tx) {
346
347         Log.info("Adding vpn interface: " + interfaceName);
348
349         NetvirtVpnUtils.createUpdateVpnInterface(vpnName, interfaceName, ipUni.getIpAddress(),
350                 uni.getMacAddress().getValue(), true, null, elanName, tx);
351
352         Log.info("Finished working on vpn instance {} interface () ", vpnName, interfaceName);
353     }
354
355     private void createDirectSubnet(Uni uni, IpUni ipUni) {
356         IpPrefix uniIpPrefix = ipUni.getIpAddress();
357         String subnetIp = NetvirtVpnUtils.getSubnetFromPrefix(uniIpPrefix);
358         IpPrefix subnetPrefix = new IpPrefix(new Ipv4Prefix(subnetIp));
359         InstanceIdentifier<Subnet> path = MefInterfaceUtils.getSubnetInstanceIdentifier(uni.getUniId(),
360                 ipUni.getIpUniId(), subnetPrefix);
361         SubnetBuilder subnet = new SubnetBuilder();
362         subnet.setUniId(uni.getUniId());
363         subnet.setIpUniId(ipUni.getIpUniId());
364         subnet.setSubnet(subnetPrefix);
365         MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, path, subnet.build());
366     }
367
368     private void removeInterfaces(InstanceIdentifier<Ipvc> ipvcId, IpvcVpn ipvcVpn, Uni uniInService, IpUni ipUni,
369             WriteTransaction tx) {
370         String uniId = uniInService.getUniId().getValue();
371         org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni uni = MefInterfaceUtils
372                 .getUni(dataBroker, uniId, LogicalDatastoreType.OPERATIONAL);
373         if (uni == null) {
374             String errorMessage = String.format("Couldn't find uni %s for ipvc", uniId);
375             Log.error(errorMessage);
376             throw new UnsupportedOperationException(errorMessage);
377         }
378
379         String vpnName = ipvcVpn.getVpnId();
380         VpnElans vpnElans = MefServicesUtils.findVpnElanForNetwork(new Identifier45(uniId), ipUni.getIpUniId(),
381                 ipvcVpn);
382         if (vpnElans == null) {
383             Log.error("Trying to remome non-operational vpn/elan for Uni {} Ip-UNi {}", uniId, ipUni.getIpUniId());
384         }
385
386         NetvirtVpnUtils.removeVpnInterfaceAdjacencies(dataBroker, vpnName, vpnElans.getElanPort());
387         // TODO : change to listener
388         NetvirtUtils.safeSleep();
389         uniQosManager.unMapUniPortBandwidthLimits(uniId, vpnElans.getElanPort());
390         removeElan(vpnElans, uniId, ipUni, tx);
391         // record Uni bw limits
392         removeVpnInterface(vpnName, vpnElans, uniId, ipUni, tx);
393         MefServicesUtils.removeOperIpvcElan(dataBroker, ipvcId, ipvcVpn.getVpnId(), uniInService.getUniId(),
394                 uniInService.getIpUniId(), vpnElans.getElanId(), vpnElans.getElanPort());
395     }
396
397     private void removeElan(VpnElans vpnElans, String uniId, IpUni ipUni, WriteTransaction tx) {
398         Long vlan = ipUni.getVlan() != null ? Long.valueOf(ipUni.getVlan().getValue()) : 0;
399         Log.info("Removing trunk interface for uni {} vlan: {}", uniId, vlan);
400         uniPortManager.removeCeVlan(uniId, vlan);
401
402         String elanName = vpnElans.getElanId();
403         String interfaceName = vpnElans.getElanPort();
404
405         Log.info("Removing elan instance {} and interface {}: ", elanName, interfaceName);
406         NetvirtVpnUtils.unregisterDirectSubnetForVpn(dataBroker, new Uuid(elanName));
407         NetvirtUtils.deleteElanInterface(interfaceName, tx);
408         NetvirtUtils.deleteElanInstance(elanName, tx);
409     }
410
411     private void removeVpnInterface(String vpnName, VpnElans vpnElans, String uniId, IpUni ipUni, WriteTransaction tx) {
412         String interfaceName = vpnElans.getElanPort();
413         Log.info("Removing vpn interface: " + interfaceName);
414         NetvirtVpnUtils.removeVpnInterface(interfaceName, tx);
415         NetvirtVpnUtils.removeVpnPortFixedIp(vpnName, ipUni.getIpAddress(), tx);
416         Log.info("Finished working on vpn instance: " + vpnName);
417     }
418
419     private void removeDirectSubnet(Uni uni, IpUni ipUni) {
420         IpPrefix uniIpPrefix = ipUni.getIpAddress();
421         String subnetIp = NetvirtVpnUtils.getSubnetFromPrefix(uniIpPrefix);
422         IpPrefix subnetPrefix = new IpPrefix(new Ipv4Prefix(subnetIp));
423         InstanceIdentifier<Subnet> path = MefInterfaceUtils.getSubnetInstanceIdentifier(uni.getUniId(),
424                 ipUni.getIpUniId(), subnetPrefix);
425         MdsalUtils.delete(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
426     }
427
428     private void updateQos(List<Uni> uniToUpdate) {
429         uniToUpdate.forEach(u -> uniQosManager.setUniBandwidthLimits(u.getUniId()));
430     }
431 }