Merge "Security Group: Allowed address pair changes"
[netvirt.git] / vpnservice / neutronvpn / neutronvpn-impl / src / main / java / org / opendaylight / netvirt / neutronvpn / NeutronPortChangeListener.java
1 /*
2  * Copyright (c) 2015 - 2016 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
11 import com.google.common.base.Optional;
12 import com.google.common.collect.Lists;
13 import java.util.ArrayList;
14 import java.util.Iterator;
15 import java.util.List;
16 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
17 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
18 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
19 import org.opendaylight.controller.md.sal.binding.api.NotificationService;
20 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.genius.mdsalutil.AbstractDataChangeListener;
23 import org.opendaylight.genius.mdsalutil.MDSALUtil;
24 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
25 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.LockManagerService;
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.ElanInstances;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceKey;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstanceKey;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.PortAddedToSubnetBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.PortRemovedFromSubnetBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
57 import org.opendaylight.yangtools.concepts.ListenerRegistration;
58 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
61
62
63 public class NeutronPortChangeListener extends AbstractDataChangeListener<Port> implements AutoCloseable {
64     private static final Logger LOG = LoggerFactory.getLogger(NeutronPortChangeListener.class);
65
66     private ListenerRegistration<DataChangeListener> listenerRegistration;
67     private final DataBroker broker;
68     private NeutronvpnManager nvpnManager;
69     private NeutronvpnNatManager nvpnNatManager;
70     private LockManagerService lockManager;
71     private NotificationPublishService notificationPublishService;
72     private NotificationService notificationService;
73
74
75     public NeutronPortChangeListener(final DataBroker db, NeutronvpnManager nVpnMgr,
76                                      NeutronvpnNatManager nVpnNatMgr,
77                                      NotificationPublishService notiPublishService, NotificationService notiService) {
78         super(Port.class);
79         broker = db;
80         nvpnManager = nVpnMgr;
81         nvpnNatManager = nVpnNatMgr;
82         notificationPublishService = notiPublishService;
83         notificationService = notiService;
84         registerListener(db);
85     }
86
87     public void setLockManager(LockManagerService lockManager) {
88         this.lockManager = lockManager;
89     }
90
91     @Override
92     public void close() throws Exception {
93         if (listenerRegistration != null) {
94             try {
95                 listenerRegistration.close();
96             } catch (final Exception e) {
97                 LOG.error("Error when cleaning up DataChangeListener.", e);
98             }
99             listenerRegistration = null;
100         }
101         LOG.info("N_Port listener Closed");
102     }
103
104
105     private void registerListener(final DataBroker db) {
106         try {
107             listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
108                     InstanceIdentifier.create(Neutron.class).child(Ports.class).child(Port.class),
109                     NeutronPortChangeListener.this, DataChangeScope.SUBTREE);
110         } catch (final Exception e) {
111             LOG.error("Neutron Manager Port DataChange listener registration fail!", e);
112             throw new IllegalStateException("Neutron Manager Port DataChange listener registration failed.", e);
113         }
114     }
115
116     @Override
117     protected void add(InstanceIdentifier<Port> identifier, Port input) {
118         if (LOG.isTraceEnabled()) {
119             LOG.trace("Adding Port : key: " + identifier + ", value=" + input);
120         }
121         Network network = NeutronvpnUtils.getNeutronNetwork(broker, input.getNetworkId());
122         if (network == null || NeutronvpnUtils.isNetworkTypeVlanOrGre(network)) {
123             //FIXME: This should be removed when support for VLAN and GRE network types is added
124             LOG.error("neutron vpn doesn't support vlan/gre network provider type for the port {} which is part of network {}.",
125                     input.getName(), network);
126             return;
127         }
128         NeutronvpnUtils.addToPortCache(input);
129
130         /* check if router interface has been created */
131         if ((input.getDeviceOwner() != null) && (input.getDeviceId() != null)) {
132             if (input.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF)) {
133                 handleRouterInterfaceAdded(input);
134                 /* nothing else to do here */
135                 return;
136             }
137         }
138         if (input.getFixedIps() != null && !input.getFixedIps().isEmpty()) {
139             handleNeutronPortCreated(input);
140         }
141     }
142
143     @Override
144     protected void remove(InstanceIdentifier<Port> identifier, Port input) {
145         if (LOG.isTraceEnabled()) {
146             LOG.trace("Removing Port : key: " + identifier + ", value=" + input);
147         }
148         Network network = NeutronvpnUtils.getNeutronNetwork(broker, input.getNetworkId());
149         if (network == null || NeutronvpnUtils.isNetworkTypeVlanOrGre(network)) {
150             //FIXME: This should be removed when support for VLAN and GRE network types is added
151             LOG.error("neutron vpn doesn't support vlan/gre network provider type for the port {} which is part of " +
152                     "network {}.", input.getName(), network);
153             return;
154         }
155         NeutronvpnUtils.removeFromPortCache(input);
156
157         if ((input.getDeviceOwner() != null) && (input.getDeviceId() != null)) {
158             if (input.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF)) {
159                 handleRouterInterfaceRemoved(input);
160                 /* nothing else to do here */
161                 return;
162             }
163         }
164         if (input.getFixedIps() != null && !input.getFixedIps().isEmpty()) {
165             handleNeutronPortDeleted(input);
166         }
167     }
168
169     @Override
170     protected void update(InstanceIdentifier<Port> identifier, Port original, Port update) {
171         if (LOG.isTraceEnabled()) {
172             LOG.trace("Updating Port : key: " + identifier + ", original value=" + original + ", update value=" +
173                     update);
174         }
175         Network network = NeutronvpnUtils.getNeutronNetwork(broker, update.getNetworkId());
176         if (network == null || NeutronvpnUtils.isNetworkTypeVlanOrGre(network)) {
177             LOG.error("neutron vpn doesn't support vlan/gre network provider type for the port {} which is part of network {}."
178                     + " Skipping the processing of Port update DCN", update.getName(), network);
179             return;
180         }
181         List<FixedIps> oldIPs = (original.getFixedIps() != null) ? original.getFixedIps() : new ArrayList<>();
182         List<FixedIps> newIPs = (update.getFixedIps() != null) ? update.getFixedIps() : new ArrayList<>();
183
184         /* check if VIF type updated as part of port binding */
185         if(NeutronvpnUtils.isPortVifTypeUpdated(original, update)) {
186             updateOfPortInterface(original, update);
187         }
188         NeutronvpnUtils.addToPortCache(update);
189
190         /* check if router interface has been updated */
191         if ((update.getDeviceOwner() != null) && (update.getDeviceId() != null)) {
192             if (update.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF)) {
193                 handleRouterInterfaceAdded(update);
194                 /* nothing else to do here */
195                 return;
196             }
197         }
198
199         handlePortSecurityUpdated(original, update);
200
201         if (!oldIPs.equals(newIPs)) {
202             Iterator<FixedIps> iterator = newIPs.iterator();
203             while (iterator.hasNext()) {
204                 FixedIps ip = iterator.next();
205                 if (oldIPs.remove(ip)) {
206                     iterator.remove();
207                 }
208             }
209             handleNeutronPortUpdated(original, update);
210         }
211     }
212
213     private void handleRouterInterfaceAdded(Port routerPort) {
214         if (routerPort.getDeviceId() != null) {
215             Uuid routerId = new Uuid(routerPort.getDeviceId());
216             Uuid infNetworkId = routerPort.getNetworkId();
217             Uuid existingVpnId = NeutronvpnUtils.getVpnForNetwork(broker, infNetworkId);
218             if (existingVpnId == null) {
219                 for (FixedIps portIP : routerPort.getFixedIps()) {
220                     if (portIP.getIpAddress().getIpv4Address() != null) {
221                         Uuid vpnId = NeutronvpnUtils.getVpnForRouter(broker, routerId, true);
222                         if (vpnId == null) {
223                             vpnId = routerId;
224                         }
225                         nvpnManager.addSubnetToVpn(vpnId, portIP.getSubnetId());
226                         String ipValue = portIP.getIpAddress().getIpv4Address().getValue();
227                         nvpnManager.updateSubnetNodeWithFixedIps(portIP.getSubnetId(), routerId,
228                                 routerPort.getUuid(), ipValue, routerPort.getMacAddress().getValue());
229                         nvpnNatManager.handleSubnetsForExternalRouter(routerId, broker);
230                         PhysAddress mac = new PhysAddress(routerPort.getMacAddress().getValue());
231                         LOG.trace("NeutronPortChangeListener Add Subnet Gateway IP {} MAC {} Interface {} VPN {}",
232                                 portIP.getIpAddress().getIpv4Address(),routerPort.getMacAddress(),
233                                 routerPort.getUuid().getValue(), vpnId.getValue());
234                         NeutronvpnUtils.createVpnPortFixedIpToPort(broker, vpnId.getValue(), ipValue, routerPort
235                                 .getUuid().getValue(), routerPort.getMacAddress().getValue(), true, true, false);
236                     } else {
237                         LOG.error("No IPv4 address assigned to port {)", routerPort.getUuid().getValue());
238                     }
239                 }
240             } else {
241                 LOG.error("Neutron network {} corresponding to router interface port {} for neutron router {} already" +
242                         " associated to VPN {}", infNetworkId.getValue(), routerPort.getUuid().getValue(), routerId
243                         .getValue(), existingVpnId.getValue());
244             }
245         }
246     }
247
248     private void handleRouterInterfaceRemoved(Port routerPort) {
249         if (routerPort.getDeviceId() != null) {
250             Uuid routerId = new Uuid(routerPort.getDeviceId());
251             for (FixedIps portIP : routerPort.getFixedIps()) {
252                 if (portIP.getIpAddress().getIpv4Address() != null) {
253                     Uuid vpnId = NeutronvpnUtils.getVpnForRouter(broker, routerId, true);
254                     if(vpnId == null) {
255                         vpnId = routerId;
256                     }
257                     nvpnManager.removeSubnetFromVpn(vpnId, portIP.getSubnetId());
258                     nvpnManager.updateSubnetNodeWithFixedIps(portIP.getSubnetId(), null,
259                             null, null, null);
260                     nvpnNatManager.handleSubnetsForExternalRouter(routerId, broker);
261                     String ipValue = portIP.getIpAddress().getIpv4Address().getValue();
262                     NeutronvpnUtils.removeVpnPortFixedIpToPort(broker, vpnId.getValue(), ipValue);
263                 } else {
264                     LOG.error("No IPv4 address assigned to port {)", routerPort.getUuid().getValue());
265                 }
266             }
267         }
268     }
269
270     private Long getVpnIdFromUuid(Uuid vpnId) {
271         long vpn = 1;
272         InstanceIdentifier<VpnInstance> id = InstanceIdentifier.builder(VpnInstanceToVpnId.class).
273                 child(VpnInstance.class, new VpnInstanceKey(vpnId.getValue())).build();
274         try {
275             Optional<VpnInstance> optional = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
276                     id);
277             if (optional.isPresent()) {
278                 vpn = optional.get().getVpnId();
279             }
280         } catch (Exception e) {
281             LOG.error("Failed to retrieve vpn instance for the Subnet .", e.getMessage());
282         }
283         return vpn;
284     }
285
286     private void handleNeutronPortCreated(Port port) {
287         if (!NeutronUtils.isPortVnicTypeNormal(port)) {
288             nvpnManager.updateSubnetmapNodeWithPorts(port.getFixedIps().get(0).getSubnetId(), null, port.getUuid());
289             LOG.info("Port {} is not a NORMAL VNIC Type port; OF Port interfaces are not created",
290                     port.getUuid().getValue());
291             return;
292         }
293         LOG.info("Of-port-interface creation");
294         // Create of-port interface for this neutron port
295         String portInterfaceName = createOfPortInterface(port);
296         LOG.debug("Creating ELAN Interface");
297         createElanInterface(port, portInterfaceName);
298         LOG.debug("Add port to subnet");
299         // add port to local Subnets DS
300         Uuid vpnId = addPortToSubnets(port);
301
302         if (vpnId != null) {
303             // create vpn-interface on this neutron port
304             LOG.debug("Adding VPN Interface");
305             nvpnManager.createVpnInterface(vpnId, port);
306             Uuid routerId = NeutronvpnUtils.getVpnMap(broker, vpnId).getRouterId();
307             if(routerId != null) {
308                 nvpnManager.addToNeutronRouterInterfacesMap(routerId, port.getUuid().getValue());
309             }
310         }
311     }
312
313     private void handleNeutronPortDeleted(Port port) {
314         if (!NeutronUtils.isPortVnicTypeNormal(port)) {
315             nvpnManager.removePortsFromSubnetmapNode(port.getFixedIps().get(0).getSubnetId(), null, port.getUuid());
316             LOG.info("Port {} is not a NORMAL VNIC Type port; OF Port interfaces are not created",
317                     port.getUuid().getValue());
318             return;
319         }
320         //dissociate fixedIP from floatingIP if associated
321         nvpnManager.dissociatefixedIPFromFloatingIP(port.getUuid().getValue());
322         LOG.debug("Remove port from subnet");
323         // remove port from local Subnets DS
324         Uuid vpnId = removePortFromSubnets(port);
325
326         if (vpnId != null) {
327             // remove vpn-interface for this neutron port
328             LOG.debug("removing VPN Interface");
329             nvpnManager.deleteVpnInterface(vpnId, port);
330         }
331
332         // Remove of-port interface for this neutron port
333         // ELAN interface is also implicitly deleted as part of this operation
334         LOG.debug("Of-port-interface removal");
335         deleteOfPortInterface(port);
336         if (vpnId != null) {
337             Uuid routerId = NeutronvpnUtils.getVpnMap(broker, vpnId).getRouterId();
338             if (routerId != null) {
339                 nvpnManager.removeFromNeutronRouterInterfacesMap(routerId, port.getUuid().getValue());
340             }
341         }
342     }
343
344     private void handleNeutronPortUpdated(Port portoriginal, Port portupdate) {
345         if (portoriginal.getFixedIps() == null || portoriginal.getFixedIps().isEmpty()) {
346             handleNeutronPortCreated(portupdate);
347             return;
348         }
349         LOG.debug("Add port to subnet");
350         // add port FixedIP to local Subnets DS
351         Uuid vpnIdup = addPortToSubnets(portupdate);
352
353         if (vpnIdup != null) {
354             nvpnManager.createVpnInterface(vpnIdup, portupdate);
355             Uuid routerId = NeutronvpnUtils.getVpnMap(broker, vpnIdup).getRouterId();
356             if(routerId != null) {
357                 nvpnManager.addToNeutronRouterInterfacesMap(routerId, portupdate.getUuid().getValue());
358             }
359         }
360
361         // remove port FixedIP from local Subnets DS
362         Uuid vpnIdor = removePortFromSubnets(portoriginal);
363
364         if (vpnIdor != null) {
365             nvpnManager.deleteVpnInterface(vpnIdor, portoriginal);
366             Uuid routerId = NeutronvpnUtils.getVpnMap(broker, vpnIdor).getRouterId();
367             if(routerId != null) {
368                 nvpnManager.removeFromNeutronRouterInterfacesMap(routerId, portoriginal.getUuid().getValue());
369             }
370         }
371     }
372
373     private void handlePortSecurityUpdated(Port portOriginal, Port portUpdated) {
374         Boolean origSecurityEnabled = NeutronvpnUtils.getPortSecurityEnabled(portOriginal);
375         Boolean updatedSecurityEnabled = NeutronvpnUtils.getPortSecurityEnabled(portUpdated);
376         String interfaceName = portUpdated.getUuid().getValue();
377         Interface portInterface = NeutronvpnUtils.getOfPortInterface(broker, portUpdated);
378         if (portInterface != null) {
379             InterfaceAclBuilder interfaceAclBuilder = null;
380             if (origSecurityEnabled != updatedSecurityEnabled) {
381                 interfaceAclBuilder = new InterfaceAclBuilder();
382                 interfaceAclBuilder.setPortSecurityEnabled(updatedSecurityEnabled);
383                 if (updatedSecurityEnabled) {
384                     // Handle security group enabled
385                     NeutronvpnUtils.populateInterfaceAclBuilder(interfaceAclBuilder, portUpdated);
386                 } else {
387                     // Handle security group disabled
388                     interfaceAclBuilder.setSecurityGroups(Lists.newArrayList());
389                     interfaceAclBuilder.setAllowedAddressPairs(Lists.newArrayList());
390                 }
391             } else {
392                 if (updatedSecurityEnabled) {
393                     // handle SG add/delete delta
394                     InterfaceAcl interfaceAcl = portInterface.getAugmentation(InterfaceAcl.class);
395                     interfaceAclBuilder = new InterfaceAclBuilder(interfaceAcl);
396                     interfaceAclBuilder.setSecurityGroups(
397                             NeutronvpnUtils.getUpdatedSecurityGroups(interfaceAcl.getSecurityGroups(),
398                                     portOriginal.getSecurityGroups(), portUpdated.getSecurityGroups()));
399                     List<AllowedAddressPairs> updatedAddressPairs = NeutronvpnUtils.getUpdatedAllowedAddressPairs(
400                             interfaceAcl.getAllowedAddressPairs(), portOriginal.getAllowedAddressPairs(),
401                             portUpdated.getAllowedAddressPairs());
402                     interfaceAclBuilder.setAllowedAddressPairs(NeutronvpnUtils.getAllowedAddressPairsForFixedIps(
403                             updatedAddressPairs, portOriginal.getMacAddress(), portOriginal.getFixedIps(),
404                             portUpdated.getFixedIps()));
405                 }
406             }
407
408             if (interfaceAclBuilder != null) {
409                 InterfaceBuilder builder = new InterfaceBuilder(portInterface).addAugmentation(InterfaceAcl.class,
410                         interfaceAclBuilder.build());
411                 InstanceIdentifier interfaceIdentifier = NeutronvpnUtils.buildVlanInterfaceIdentifier(interfaceName);
412                 MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, interfaceIdentifier, builder.build());
413             }
414         } else {
415             LOG.error("Interface {} is not present", interfaceName);
416         }
417     }
418
419     private String createOfPortInterface(Port port) {
420         Interface inf = createInterface(port);
421         String infName = inf.getName();
422
423         LOG.debug("Creating OFPort Interface {}", infName);
424         InstanceIdentifier interfaceIdentifier = NeutronvpnUtils.buildVlanInterfaceIdentifier(infName);
425         try {
426             Optional<Interface> optionalInf = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
427                     interfaceIdentifier);
428             if (!optionalInf.isPresent()) {
429                 MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, interfaceIdentifier, inf);
430             } else {
431                 LOG.error("Interface {} is already present", infName);
432             }
433         } catch (Exception e) {
434             LOG.error("failed to create interface {} due to the exception {} ", infName, e.getMessage());
435         }
436
437         return infName;
438     }
439
440     private Interface createInterface(Port port) {
441         String parentRefName = NeutronvpnUtils.getVifPortName(port);
442         String interfaceName = port.getUuid().getValue();
443         IfL2vlan.L2vlanMode l2VlanMode = IfL2vlan.L2vlanMode.Trunk;
444         InterfaceBuilder interfaceBuilder = new InterfaceBuilder();
445         IfL2vlanBuilder ifL2vlanBuilder = new IfL2vlanBuilder();
446
447         Network network = NeutronvpnUtils.getNeutronNetwork(broker, port.getNetworkId());
448         ifL2vlanBuilder.setL2vlanMode(l2VlanMode);
449
450         if(parentRefName != null) {
451             ParentRefsBuilder parentRefsBuilder = new ParentRefsBuilder().setParentInterface(parentRefName);
452             interfaceBuilder.addAugmentation(ParentRefs.class, parentRefsBuilder.build());
453         }
454
455         interfaceBuilder.setEnabled(true).setName(interfaceName).setType(L2vlan.class)
456                 .addAugmentation(IfL2vlan.class, ifL2vlanBuilder.build());
457
458         if (NeutronvpnUtils.isPortSecurityEnabled(port)) {
459             InterfaceAclBuilder interfaceAclBuilder = new InterfaceAclBuilder();
460             interfaceAclBuilder.setPortSecurityEnabled(true);
461             NeutronvpnUtils.populateInterfaceAclBuilder(interfaceAclBuilder, port);
462             interfaceBuilder.addAugmentation(InterfaceAcl.class, interfaceAclBuilder.build());
463         }
464         return interfaceBuilder.build();
465     }
466
467     private void deleteOfPortInterface(Port port) {
468         String name = port.getUuid().getValue();
469         LOG.debug("Removing OFPort Interface {}", name);
470         InstanceIdentifier interfaceIdentifier = NeutronvpnUtils.buildVlanInterfaceIdentifier(name);
471         try {
472             Optional<Interface> optionalInf = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
473                     interfaceIdentifier);
474             if (optionalInf.isPresent()) {
475                 MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, interfaceIdentifier);
476             } else {
477                 LOG.error("Interface {} is not present", name);
478             }
479         } catch (Exception e) {
480             LOG.error("Failed to delete interface {} due to the exception {}", name, e.getMessage());
481         }
482     }
483
484     private Interface updateInterface(Port original, Port update) {
485         String parentRefName = NeutronvpnUtils.getVifPortName(update);
486         String interfaceName = original.getUuid().getValue();
487         InterfaceBuilder interfaceBuilder = new InterfaceBuilder();
488
489         if(parentRefName != null) {
490             ParentRefsBuilder parentRefsBuilder = new ParentRefsBuilder().setParentInterface(parentRefName);
491             interfaceBuilder.addAugmentation(ParentRefs.class, parentRefsBuilder.build());
492         }
493
494         interfaceBuilder.setName(interfaceName);
495         return interfaceBuilder.build();
496     }
497
498     private String updateOfPortInterface(Port original, Port updated) {
499         Interface inf = updateInterface(original, updated);
500         String infName = inf.getName();
501
502         LOG.debug("Updating OFPort Interface {}", infName);
503         InstanceIdentifier interfaceIdentifier = NeutronvpnUtils.buildVlanInterfaceIdentifier(infName);
504         try {
505             Optional<Interface> optionalInf = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
506                     interfaceIdentifier);
507             if (optionalInf.isPresent()) {
508                 MDSALUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, interfaceIdentifier, inf);
509             } else {
510                 LOG.error("Interface {} doesn't exist", infName);
511             }
512         } catch (Exception e) {
513             LOG.error("failed to update interface {} due to the exception {} ", infName, e.getMessage());
514         }
515
516         return infName;
517     }
518
519     private void createElanInterface(Port port, String name) {
520         String elanInstanceName = port.getNetworkId().getValue();
521         List<PhysAddress> physAddresses = new ArrayList<>();
522         physAddresses.add(new PhysAddress(port.getMacAddress().getValue()));
523
524         InstanceIdentifier<ElanInterface> id = InstanceIdentifier.builder(ElanInterfaces.class).child(ElanInterface
525                 .class, new ElanInterfaceKey(name)).build();
526         ElanInterface elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName)
527                 .setName(name).setStaticMacEntries(physAddresses).setKey(new ElanInterfaceKey(name)).build();
528         MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, id, elanInterface);
529         LOG.debug("Creating new ELan Interface {}", elanInterface);
530     }
531
532     // adds port to subnet list and creates vpnInterface
533     private Uuid addPortToSubnets(Port port) {
534         Uuid subnetId = null;
535         Uuid vpnId = null;
536         String infName = port.getUuid().getValue();
537         Subnetmap subnetmap = null;
538         boolean isLockAcquired = false;
539         String lockName = port.getUuid().getValue();
540         String elanInstanceName = port.getNetworkId().getValue();
541         InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child
542                 (ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
543         Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
544                 elanIdentifierId);
545         long elanTag = elanInstance.get().getElanTag();
546
547         // find the subnet to which this port is associated
548         FixedIps ip = port.getFixedIps().get(0);
549         subnetId = ip.getSubnetId();
550         subnetmap = nvpnManager.updateSubnetmapNodeWithPorts(subnetId, port.getUuid(), null);
551         if (subnetmap != null) {
552             vpnId = subnetmap.getVpnId();
553         }
554         if (vpnId != null) {
555             try {
556                 isLockAcquired = NeutronvpnUtils.lock(lockManager, lockName);
557                 checkAndPublishPortAddNotification(subnetmap.getSubnetIp(), subnetId, port.getUuid(), elanTag);
558                 LOG.debug("Port added to subnet notification sent");
559             } catch (Exception e) {
560                 LOG.error("Port added to subnet notification failed", e);
561             } finally {
562                 if (isLockAcquired) {
563                     NeutronvpnUtils.unlock(lockManager, lockName);
564                 }
565             }
566         }
567         return vpnId;
568     }
569
570     private Uuid removePortFromSubnets(Port port) {
571         Uuid subnetId = null;
572         Uuid vpnId = null;
573         Subnetmap subnetmap = null;
574         boolean isLockAcquired = false;
575         String lockName = port.getUuid().getValue();
576         String elanInstanceName = port.getNetworkId().getValue();
577         InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child
578                 (ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
579         Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
580                 elanIdentifierId);
581         long elanTag = elanInstance.get().getElanTag();
582
583         // find the subnet to which this port is associated
584         FixedIps ip = port.getFixedIps().get(0);
585         subnetId = ip.getSubnetId();
586         subnetmap = nvpnManager.removePortsFromSubnetmapNode(subnetId, port.getUuid(), null);
587         if (subnetmap != null) {
588             vpnId = subnetmap.getVpnId();
589         }
590         if (vpnId != null) {
591             try {
592                 isLockAcquired = NeutronvpnUtils.lock(lockManager, lockName);
593                 checkAndPublishPortRemoveNotification(subnetmap.getSubnetIp(), subnetId, port.getUuid(), elanTag);
594                 LOG.debug("Port removed from subnet notification sent");
595             } catch (Exception e) {
596                 LOG.error("Port removed from subnet notification failed", e);
597             } finally {
598                 if (isLockAcquired) {
599                     NeutronvpnUtils.unlock(lockManager, lockName);
600                 }
601             }
602         }
603         return vpnId;
604     }
605
606     private void checkAndPublishPortAddNotification(String subnetIp, Uuid subnetId, Uuid portId, Long elanTag) throws
607             InterruptedException {
608         PortAddedToSubnetBuilder builder = new PortAddedToSubnetBuilder();
609
610         LOG.info("publish notification called");
611
612         builder.setSubnetIp(subnetIp);
613         builder.setSubnetId(subnetId);
614         builder.setPortId(portId);
615         builder.setElanTag(elanTag);
616
617         notificationPublishService.putNotification(builder.build());
618     }
619
620     private void checkAndPublishPortRemoveNotification(String subnetIp, Uuid subnetId, Uuid portId, Long elanTag)
621             throws InterruptedException {
622         PortRemovedFromSubnetBuilder builder = new PortRemovedFromSubnetBuilder();
623
624         LOG.info("publish notification called");
625
626         builder.setPortId(portId);
627         builder.setSubnetIp(subnetIp);
628         builder.setSubnetId(subnetId);
629         builder.setElanTag(elanTag);
630
631         notificationPublishService.putNotification(builder.build());
632     }
633
634 }