Qos implemented as separate service. All qos related codes from neutronvpn
[netvirt.git] / vpnservice / neutronvpn / neutronvpn-impl / src / main / java / org / opendaylight / netvirt / neutronvpn / NeutronPortChangeListener.java
1 /*
2  * Copyright (c) 2015, 2017 Ericsson India Global Services Pvt Ltd. 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 package org.opendaylight.netvirt.neutronvpn;
9
10 import static org.opendaylight.netvirt.neutronvpn.NeutronvpnUtils.buildfloatingIpIdToPortMappingIdentifier;
11
12 import com.google.common.base.Optional;
13 import com.google.common.util.concurrent.ListenableFuture;
14
15 import java.util.ArrayList;
16 import java.util.List;
17
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
20 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
23 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
24 import org.opendaylight.genius.mdsalutil.MDSALUtil;
25 import org.opendaylight.genius.mdsalutil.NwConstants;
26 import org.opendaylight.netvirt.elanmanager.api.IElanService;
27 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
28 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAcl;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAclBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceKey;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
52 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
55
56 public class NeutronPortChangeListener extends AsyncDataTreeChangeListenerBase<Port, NeutronPortChangeListener>
57         implements AutoCloseable {
58     private static final Logger LOG = LoggerFactory.getLogger(NeutronPortChangeListener.class);
59     private final DataBroker dataBroker;
60     private final NeutronvpnManager nvpnManager;
61     private final NeutronvpnNatManager nvpnNatManager;
62     private final NotificationPublishService notificationPublishService;
63     private final NeutronSubnetGwMacResolver gwMacResolver;
64     private final IElanService elanService;
65
66     public NeutronPortChangeListener(final DataBroker dataBroker,
67                                      final NeutronvpnManager neutronvpnManager,
68                                      final NeutronvpnNatManager neutronvpnNatManager,
69                                      final NotificationPublishService notiPublishService,
70                                      final NeutronSubnetGwMacResolver gwMacResolver,
71                                      final IElanService elanService) {
72         super(Port.class, NeutronPortChangeListener.class);
73         this.dataBroker = dataBroker;
74         nvpnManager = neutronvpnManager;
75         nvpnNatManager = neutronvpnNatManager;
76         notificationPublishService = notiPublishService;
77         this.gwMacResolver = gwMacResolver;
78         this.elanService = elanService;
79     }
80
81
82     public void start() {
83         LOG.info("{} start", getClass().getSimpleName());
84         registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
85     }
86
87     @Override
88     protected InstanceIdentifier<Port> getWildCardPath() {
89         return InstanceIdentifier.create(Neutron.class).child(Ports.class).child(Port.class);
90     }
91
92     @Override
93     protected NeutronPortChangeListener getDataTreeChangeListener() {
94         return NeutronPortChangeListener.this;
95     }
96
97
98     @Override
99     protected void add(InstanceIdentifier<Port> identifier, Port input) {
100         String portName = input.getUuid().getValue();
101         LOG.trace("Adding Port : key: {}, value={}", identifier, input);
102         Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, input.getNetworkId());
103         if (network == null || !NeutronvpnUtils.isNetworkTypeSupported(network)) {
104             LOG.warn("neutron vpn received a port add() for a network without a provider extension augmentation "
105                             + "or with an unsupported network type for the port {} which is part of network {}",
106                     portName, network);
107             return;
108         }
109         NeutronvpnUtils.addToPortCache(input);
110
111         /* check if router interface has been created */
112         if ((input.getDeviceOwner() != null) && (input.getDeviceId() != null)) {
113             if (input.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF)) {
114                 handleRouterInterfaceAdded(input);
115                 /* nothing else to do here */
116                 return;
117             }
118             if (NeutronConstants.DEVICE_OWNER_GATEWAY_INF.equals(input.getDeviceOwner())) {
119                 handleRouterGatewayUpdated(input);
120             } else if (NeutronConstants.DEVICE_OWNER_FLOATING_IP.equals(input.getDeviceOwner())) {
121
122                 // populate floating-ip uuid and floating-ip port attributes (uuid, mac and subnet id for the ONLY
123                 // fixed IP) to be used by NAT, depopulated in NATService once mac is retrieved in the removal path
124                 addToFloatingIpPortInfo(new Uuid(input.getDeviceId()), input.getUuid(), input.getFixedIps().get(0)
125                                 .getSubnetId(), input.getMacAddress().getValue());
126
127                 elanService.handleKnownL3DmacAddress(input.getMacAddress().getValue(), input.getNetworkId().getValue(),
128                         NwConstants.ADD_FLOW);
129             }
130         }
131         if (input.getFixedIps() != null && !input.getFixedIps().isEmpty()) {
132             handleNeutronPortCreated(input);
133         }
134     }
135
136     @Override
137     protected void remove(InstanceIdentifier<Port> identifier, Port input) {
138         LOG.trace("Removing Port : key: {}, value={}", identifier, input);
139         Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, input.getNetworkId());
140         if (network == null || !NeutronvpnUtils.isNetworkTypeSupported(network)) {
141             String portName = input.getUuid().getValue();
142             LOG.warn("neutron vpn received a port remove() for a network without a provider extension augmentation "
143                             + "or with an unsupported network type for the port {} which is part of network {}",
144                     portName, network);
145             return;
146         }
147         NeutronvpnUtils.removeFromPortCache(input);
148
149         if ((input.getDeviceOwner() != null) && (input.getDeviceId() != null)) {
150             if (input.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF)) {
151                 handleRouterInterfaceRemoved(input);
152                 /* nothing else to do here */
153                 return;
154             } else if (NeutronConstants.DEVICE_OWNER_GATEWAY_INF.equals(input.getDeviceOwner())
155                     || NeutronConstants.DEVICE_OWNER_FLOATING_IP.equals(input.getDeviceOwner())) {
156                 elanService.handleKnownL3DmacAddress(input.getMacAddress().getValue(), input.getNetworkId().getValue(),
157                         NwConstants.DEL_FLOW);
158             }
159         }
160         if (input.getFixedIps() != null && !input.getFixedIps().isEmpty()) {
161             handleNeutronPortDeleted(input);
162         }
163     }
164
165     @Override
166     // TODO Clean up the exception handling
167     @SuppressWarnings("checkstyle:IllegalCatch")
168     protected void update(InstanceIdentifier<Port> identifier, Port original, Port update) {
169         final String portName = update.getUuid().getValue();
170         LOG.trace("Updating Port : key: {}, original value={}, update value={}", identifier, original, update);
171         Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, update.getNetworkId());
172         if (network == null || !NeutronvpnUtils.isNetworkTypeSupported(network)) {
173             LOG.warn("neutron vpn received a port update() for a network without a provider extension augmentation "
174                     + "or with an unsupported network type for the port {} which is part of network {}",
175                     portName, network);
176             return;
177         }
178         NeutronvpnUtils.addToPortCache(update);
179
180         /* check if router interface has been updated */
181         if ((update.getDeviceOwner() != null) && (update.getDeviceId() != null)) {
182             if (update.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF)) {
183                 handleRouterInterfaceAdded(update);
184                 /* nothing else to do here */
185                 return;
186             }
187         }
188
189         // check if port security enabled/disabled as part of port update
190         boolean origSecurityEnabled = NeutronvpnUtils.getPortSecurityEnabled(original);
191         boolean updatedSecurityEnabled = NeutronvpnUtils.getPortSecurityEnabled(update);
192
193         if (origSecurityEnabled || updatedSecurityEnabled) {
194             InstanceIdentifier interfaceIdentifier = NeutronvpnUtils.buildVlanInterfaceIdentifier(portName);
195             final DataStoreJobCoordinator portDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
196             portDataStoreCoordinator.enqueueJob("PORT- " + portName, () -> {
197                 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
198                 try {
199                     Optional<Interface> optionalInf = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
200                             .CONFIGURATION, interfaceIdentifier);
201                     if (optionalInf.isPresent()) {
202                         InterfaceBuilder interfaceBuilder = new InterfaceBuilder(optionalInf.get());
203                         if (origSecurityEnabled || updatedSecurityEnabled) {
204                             InterfaceAcl infAcl = handlePortSecurityUpdated(original, update,
205                                     origSecurityEnabled, updatedSecurityEnabled, interfaceBuilder).build();
206                             interfaceBuilder.addAugmentation(InterfaceAcl.class, infAcl);
207                         }
208                         LOG.info("Of-port-interface updation for port {}", portName);
209                         // Update OFPort interface for this neutron port
210                         wrtConfigTxn.put(LogicalDatastoreType.CONFIGURATION, interfaceIdentifier,
211                                 interfaceBuilder.build());
212                     } else {
213                         LOG.error("Interface {} is not present", portName);
214                     }
215                 } catch (Exception e) {
216                     LOG.error("Failed to update interface {} due to the exception {}", portName, e);
217                 }
218                 List<ListenableFuture<Void>> futures = new ArrayList<>();
219                 futures.add(wrtConfigTxn.submit());
220                 return futures;
221             });
222         }
223         List<FixedIps> oldIPs = (original.getFixedIps() != null) ? original.getFixedIps() : new ArrayList<>();
224         List<FixedIps> newIPs = (update.getFixedIps() != null) ? update.getFixedIps() : new ArrayList<>();
225         if (!oldIPs.equals(newIPs)) {
226             newIPs.removeIf(oldIPs::remove);
227             handleNeutronPortUpdated(original, update);
228         }
229         if (NeutronConstants.DEVICE_OWNER_GATEWAY_INF.equals(update.getDeviceOwner())) {
230             handleRouterGatewayUpdated(update);
231         } else if (NeutronConstants.DEVICE_OWNER_FLOATING_IP.equals(update.getDeviceOwner())) {
232             elanService.handleKnownL3DmacAddress(update.getMacAddress().getValue(), update.getNetworkId().getValue(),
233                     NwConstants.ADD_FLOW);
234         }
235     }
236
237     private void handleRouterInterfaceAdded(Port routerPort) {
238         if (routerPort.getDeviceId() != null) {
239             Uuid routerId = new Uuid(routerPort.getDeviceId());
240             Uuid infNetworkId = routerPort.getNetworkId();
241             Uuid existingVpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, infNetworkId);
242
243             elanService.handleKnownL3DmacAddress(routerPort.getMacAddress().getValue(), infNetworkId.getValue(),
244                     NwConstants.ADD_FLOW);
245             if (existingVpnId == null) {
246                 for (FixedIps portIP : routerPort.getFixedIps()) {
247                     Uuid vpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
248                     if (vpnId == null) {
249                         vpnId = routerId;
250                     }
251                     // NOTE:  Please donot change the order of calls to updateSubnetNodeWithFixedIPs
252                     // and addSubnetToVpn here
253                     String ipValue = String.valueOf(portIP.getIpAddress().getValue());
254                     nvpnManager.updateSubnetNodeWithFixedIps(portIP.getSubnetId(), routerId,
255                             routerPort.getUuid(), ipValue, routerPort.getMacAddress().getValue());
256                     nvpnManager.addSubnetToVpn(vpnId, portIP.getSubnetId());
257                     nvpnNatManager.handleSubnetsForExternalRouter(routerId, dataBroker);
258                     PhysAddress mac = new PhysAddress(routerPort.getMacAddress().getValue());
259                     LOG.trace("NeutronPortChangeListener Add Subnet Gateway IP {} MAC {} Interface {} VPN {}",
260                             ipValue, routerPort.getMacAddress(),
261                             routerPort.getUuid().getValue(), vpnId.getValue());
262                     // ping responder for router interfaces
263                     nvpnManager.createVpnInterface(vpnId, routerId, routerPort, null);
264                 }
265             } else {
266                 LOG.error("Neutron network {} corresponding to router interface port {} for neutron router {} already"
267                     + " associated to VPN {}", infNetworkId.getValue(), routerPort.getUuid().getValue(),
268                     routerId.getValue(), existingVpnId.getValue());
269             }
270         }
271     }
272
273     private void handleRouterInterfaceRemoved(Port routerPort) {
274         if (routerPort.getDeviceId() != null) {
275             Uuid routerId = new Uuid(routerPort.getDeviceId());
276             Uuid infNetworkId = routerPort.getNetworkId();
277
278             elanService.handleKnownL3DmacAddress(routerPort.getMacAddress().getValue(), infNetworkId.getValue(),
279                     NwConstants.DEL_FLOW);
280             for (FixedIps portIP : routerPort.getFixedIps()) {
281                 Uuid vpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
282                 if (vpnId == null) {
283                     vpnId = routerId;
284                 }
285                 // NOTE:  Please donot change the order of calls to removeSubnetFromVpn and
286                 // and updateSubnetNodeWithFixedIPs
287                 nvpnManager.removeSubnetFromVpn(vpnId, portIP.getSubnetId());
288                 nvpnManager.updateSubnetNodeWithFixedIps(portIP.getSubnetId(), null,
289                         null, null, null);
290                 nvpnNatManager.handleSubnetsForExternalRouter(routerId, dataBroker);
291                 String ipValue = String.valueOf(portIP.getIpAddress().getValue());
292                 NeutronvpnUtils.removeVpnPortFixedIpToPort(dataBroker, vpnId.getValue(),
293                         ipValue, null /*writeTransaction*/);
294                 // ping responder for router interfaces
295                 nvpnManager.deleteVpnInterface(vpnId, routerId, routerPort, null);
296             }
297         }
298     }
299
300     private void handleRouterGatewayUpdated(Port routerGwPort) {
301         Uuid routerId = new Uuid(routerGwPort.getDeviceId());
302         Uuid networkId = routerGwPort.getNetworkId();
303         elanService.handleKnownL3DmacAddress(routerGwPort.getMacAddress().getValue(), networkId.getValue(),
304                 NwConstants.ADD_FLOW);
305
306         Router router = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
307         if (router == null) {
308             LOG.warn("No router found for router GW port {} router id {}", routerGwPort.getUuid(), routerId.getValue());
309             return;
310         }
311         gwMacResolver.sendArpRequestsToExtGateways(router);
312     }
313
314     private void handleNeutronPortCreated(final Port port) {
315         final String portName = port.getUuid().getValue();
316         final Uuid portId = port.getUuid();
317         final Uuid subnetId = port.getFixedIps().get(0).getSubnetId();
318         final DataStoreJobCoordinator portDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
319         portDataStoreCoordinator.enqueueJob("PORT- " + portName, () -> {
320             WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
321             List<ListenableFuture<Void>> futures = new ArrayList<>();
322
323             // add direct port to subnetMaps config DS
324             if (!NeutronUtils.isPortVnicTypeNormal(port)) {
325                 nvpnManager.updateSubnetmapNodeWithPorts(subnetId, null, portId);
326                 LOG.info("Port {} is not a NORMAL VNIC Type port; OF Port interfaces are not created", portName);
327                 futures.add(wrtConfigTxn.submit());
328                 return futures;
329             }
330             LOG.info("Of-port-interface creation for port {}", portName);
331             // Create of-port interface for this neutron port
332             String portInterfaceName = createOfPortInterface(port, wrtConfigTxn);
333             LOG.debug("Creating ELAN Interface for port {}", portName);
334             createElanInterface(port, portInterfaceName, wrtConfigTxn);
335
336             Subnetmap subnetMap = nvpnManager.updateSubnetmapNodeWithPorts(subnetId, portId, null);
337             Uuid vpnId = (subnetMap != null) ? subnetMap.getVpnId() : null;
338             Uuid routerId = (subnetMap != null) ? subnetMap.getRouterId() : null;
339             if (vpnId != null) {
340                 // create vpn-interface on this neutron port
341                 LOG.debug("Adding VPN Interface for port {}", portName);
342                 nvpnManager.createVpnInterface(vpnId, routerId, port, wrtConfigTxn);
343             }
344             futures.add(wrtConfigTxn.submit());
345             return futures;
346         });
347     }
348
349     private void handleNeutronPortDeleted(final Port port) {
350         final String portName = port.getUuid().getValue();
351         final Uuid portId = port.getUuid();
352         final Uuid subnetId = port.getFixedIps().get(0).getSubnetId();
353         final DataStoreJobCoordinator portDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
354         portDataStoreCoordinator.enqueueJob("PORT- " + portName, () -> {
355             WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
356             List<ListenableFuture<Void>> futures = new ArrayList<>();
357
358             // remove direct port from subnetMaps config DS
359             if (!NeutronUtils.isPortVnicTypeNormal(port)) {
360                 nvpnManager.removePortsFromSubnetmapNode(subnetId, null, portId);
361                 LOG.info("Port {} is not a NORMAL VNIC Type port; OF Port interfaces are not created", portName);
362                 futures.add(wrtConfigTxn.submit());
363                 return futures;
364             }
365             Subnetmap subnetMap = nvpnManager.removePortsFromSubnetmapNode(subnetId, portId, null);
366             Uuid vpnId = (subnetMap != null) ? subnetMap.getVpnId() : null;
367             Uuid routerId = (subnetMap != null) ? subnetMap.getRouterId() : null;
368             if (vpnId != null) {
369                 // remove vpn-interface for this neutron port
370                 LOG.debug("removing VPN Interface for port {}", portName);
371                 nvpnManager.deleteVpnInterface(vpnId, routerId, port, wrtConfigTxn);
372             }
373             // Remove of-port interface for this neutron port
374             // ELAN interface is also implicitly deleted as part of this operation
375             LOG.debug("Of-port-interface removal for port {}", portName);
376             deleteOfPortInterface(port, wrtConfigTxn);
377             //dissociate fixedIP from floatingIP if associated
378             nvpnManager.dissociatefixedIPFromFloatingIP(port.getUuid().getValue());
379             futures.add(wrtConfigTxn.submit());
380             return futures;
381         });
382     }
383
384     private void handleNeutronPortUpdated(final Port portoriginal, final Port portupdate) {
385         if (portoriginal.getFixedIps() == null || portoriginal.getFixedIps().isEmpty()) {
386             handleNeutronPortCreated(portupdate);
387             return;
388         }
389
390         if (portupdate.getFixedIps() == null || portupdate.getFixedIps().isEmpty()) {
391             LOG.debug("Ignoring portUpdate (fixed_ip removal) for port {} as this case is handled "
392                       + "during subnet deletion event.", portupdate.getUuid().getValue());
393             return;
394         }
395
396         final DataStoreJobCoordinator portDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
397         portDataStoreCoordinator.enqueueJob("PORT- " + portupdate.getUuid().getValue(), () -> {
398             WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
399             Uuid vpnIdNew = null;
400             final Uuid subnetIdOr = portupdate.getFixedIps().get(0).getSubnetId();
401             final Uuid subnetIdUp = portupdate.getFixedIps().get(0).getSubnetId();
402             // check if subnet UUID has changed upon change in fixedIP
403             final Boolean subnetUpdated = subnetIdUp.equals(subnetIdOr) ? false : true;
404
405             if (subnetUpdated) {
406                 Subnetmap subnetMapOld = nvpnManager.removePortsFromSubnetmapNode(subnetIdOr, portoriginal
407                         .getUuid(), null);
408                 Uuid vpnIdOld = (subnetMapOld != null) ? subnetMapOld.getVpnId() : null;
409                 Subnetmap subnetMapNew = nvpnManager.updateSubnetmapNodeWithPorts(subnetIdUp, portupdate
410                                 .getUuid(), null);
411                 vpnIdNew = (subnetMapNew != null) ? subnetMapNew.getVpnId() : null;
412             }
413             if (!subnetUpdated) {
414                 Subnetmap subnetmap = NeutronvpnUtils.getSubnetmap(dataBroker, subnetIdUp);
415                 vpnIdNew = subnetmap != null ? subnetmap.getVpnId() : null;
416             }
417             if (vpnIdNew != null) {
418                 // remove vpn-interface for this neutron port
419                 LOG.debug("removing VPN Interface for port {}", portupdate.getUuid().getValue());
420                 nvpnManager.deleteVpnInterface(vpnIdNew, null, portupdate, wrtConfigTxn);
421                 // create vpn-interface on this neutron port
422                 LOG.debug("Adding VPN Interface for port {}", portupdate.getUuid().getValue());
423                 nvpnManager.createVpnInterface(vpnIdNew, null, portupdate, wrtConfigTxn);
424             }
425             List<ListenableFuture<Void>> futures = new ArrayList<>();
426             futures.add(wrtConfigTxn.submit());
427             return futures;
428         });
429     }
430
431     private static InterfaceAclBuilder handlePortSecurityUpdated(Port portOriginal, Port portUpdated, boolean
432             origSecurityEnabled, boolean updatedSecurityEnabled, InterfaceBuilder interfaceBuilder) {
433         String interfaceName = portUpdated.getUuid().getValue();
434         InterfaceAclBuilder interfaceAclBuilder = null;
435         if (origSecurityEnabled != updatedSecurityEnabled) {
436             interfaceAclBuilder = new InterfaceAclBuilder();
437             interfaceAclBuilder.setPortSecurityEnabled(updatedSecurityEnabled);
438             if (updatedSecurityEnabled) {
439                 // Handle security group enabled
440                 NeutronvpnUtils.populateInterfaceAclBuilder(interfaceAclBuilder, portUpdated);
441             } else {
442                 // Handle security group disabled
443                 interfaceAclBuilder.setSecurityGroups(new ArrayList<>());
444                 interfaceAclBuilder.setAllowedAddressPairs(new ArrayList<>());
445             }
446         } else {
447             if (updatedSecurityEnabled) {
448                 // handle SG add/delete delta
449                 InterfaceAcl interfaceAcl = interfaceBuilder.getAugmentation(InterfaceAcl.class);
450                 interfaceAclBuilder = new InterfaceAclBuilder(interfaceAcl);
451                 interfaceAclBuilder.setSecurityGroups(
452                         NeutronvpnUtils.getUpdatedSecurityGroups(interfaceAcl.getSecurityGroups(),
453                                 portOriginal.getSecurityGroups(), portUpdated.getSecurityGroups()));
454                 List<AllowedAddressPairs> updatedAddressPairs = NeutronvpnUtils.getUpdatedAllowedAddressPairs(
455                         interfaceAcl.getAllowedAddressPairs(), portOriginal.getAllowedAddressPairs(),
456                         portUpdated.getAllowedAddressPairs());
457                 interfaceAclBuilder.setAllowedAddressPairs(NeutronvpnUtils.getAllowedAddressPairsForFixedIps(
458                         updatedAddressPairs, portOriginal.getMacAddress(), portOriginal.getFixedIps(),
459                         portUpdated.getFixedIps()));
460             }
461         }
462         return interfaceAclBuilder;
463     }
464
465     // TODO Clean up the exception handling
466     @SuppressWarnings("checkstyle:IllegalCatch")
467     private String createOfPortInterface(Port port, WriteTransaction wrtConfigTxn) {
468         Interface inf = createInterface(port);
469         String infName = inf.getName();
470
471         LOG.debug("Creating OFPort Interface {}", infName);
472         InstanceIdentifier interfaceIdentifier = NeutronvpnUtils.buildVlanInterfaceIdentifier(infName);
473         try {
474             Optional<Interface> optionalInf = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
475                     interfaceIdentifier);
476             if (!optionalInf.isPresent()) {
477                 wrtConfigTxn.put(LogicalDatastoreType.CONFIGURATION, interfaceIdentifier, inf);
478             } else {
479                 LOG.warn("Interface {} is already present", infName);
480             }
481         } catch (Exception e) {
482             LOG.error("failed to create interface {} due to the exception {} ", infName, e.getMessage());
483         }
484         return infName;
485     }
486
487     private Interface createInterface(Port port) {
488         String interfaceName = port.getUuid().getValue();
489         IfL2vlan.L2vlanMode l2VlanMode = IfL2vlan.L2vlanMode.Trunk;
490         InterfaceBuilder interfaceBuilder = new InterfaceBuilder();
491         IfL2vlanBuilder ifL2vlanBuilder = new IfL2vlanBuilder();
492         ifL2vlanBuilder.setL2vlanMode(l2VlanMode);
493
494         interfaceBuilder.setEnabled(true).setName(interfaceName).setType(L2vlan.class)
495                 .addAugmentation(IfL2vlan.class, ifL2vlanBuilder.build());
496
497         if (NeutronvpnUtils.getPortSecurityEnabled(port)) {
498             InterfaceAclBuilder interfaceAclBuilder = new InterfaceAclBuilder();
499             interfaceAclBuilder.setPortSecurityEnabled(true);
500             NeutronvpnUtils.populateInterfaceAclBuilder(interfaceAclBuilder, port);
501             interfaceBuilder.addAugmentation(InterfaceAcl.class, interfaceAclBuilder.build());
502         }
503         return interfaceBuilder.build();
504     }
505
506     // TODO Clean up the exception handling
507     @SuppressWarnings("checkstyle:IllegalCatch")
508     private void deleteOfPortInterface(Port port, WriteTransaction wrtConfigTxn) {
509         String name = port.getUuid().getValue();
510         LOG.debug("Removing OFPort Interface {}", name);
511         InstanceIdentifier interfaceIdentifier = NeutronvpnUtils.buildVlanInterfaceIdentifier(name);
512         try {
513             Optional<Interface> optionalInf = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
514                     interfaceIdentifier);
515             if (optionalInf.isPresent()) {
516                 wrtConfigTxn.delete(LogicalDatastoreType.CONFIGURATION, interfaceIdentifier);
517             } else {
518                 LOG.error("Interface {} is not present", name);
519             }
520         } catch (Exception e) {
521             LOG.error("Failed to delete interface {} due to the exception {}", name, e.getMessage());
522         }
523     }
524
525     private void createElanInterface(Port port, String name, WriteTransaction wrtConfigTxn) {
526         String elanInstanceName = port.getNetworkId().getValue();
527         List<PhysAddress> physAddresses = new ArrayList<>();
528         physAddresses.add(new PhysAddress(port.getMacAddress().getValue()));
529
530         InstanceIdentifier<ElanInterface> id = InstanceIdentifier.builder(ElanInterfaces.class).child(ElanInterface
531                 .class, new ElanInterfaceKey(name)).build();
532         ElanInterface elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName)
533                 .setName(name).setStaticMacEntries(physAddresses).setKey(new ElanInterfaceKey(name)).build();
534         wrtConfigTxn.put(LogicalDatastoreType.CONFIGURATION, id, elanInterface);
535         LOG.debug("Creating new ELan Interface {}", elanInterface);
536     }
537
538     // TODO Clean up the exception handling
539     @SuppressWarnings("checkstyle:IllegalCatch")
540     private void addToFloatingIpPortInfo(Uuid floatingIpId, Uuid floatingIpPortId, Uuid floatingIpPortSubnetId, String
541                                          floatingIpPortMacAddress) {
542         InstanceIdentifier id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
543         try {
544             FloatingIpIdToPortMappingBuilder floatingipIdToPortMacMappingBuilder = new
545                 FloatingIpIdToPortMappingBuilder().setKey(new FloatingIpIdToPortMappingKey(floatingIpId))
546                 .setFloatingIpId(floatingIpId).setFloatingIpPortId(floatingIpPortId)
547                 .setFloatingIpPortSubnetId(floatingIpPortSubnetId)
548                 .setFloatingIpPortMacAddress(floatingIpPortMacAddress);
549             LOG.debug("Creating floating IP UUID {} to Floating IP neutron port {} mapping in Floating IP"
550                 + " Port Info Config DS", floatingIpId.getValue(), floatingIpPortId.getValue());
551             MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id,
552                 floatingipIdToPortMacMappingBuilder.build());
553         } catch (Exception e) {
554             LOG.error("Creating floating IP UUID {} to Floating IP neutron port {} mapping in Floating IP"
555                 + " Port Info Config DS failed with exception {}",
556                 floatingIpId.getValue(), floatingIpPortId.getValue(), e);
557         }
558     }
559 }