Remove unused parameters
[netvirt.git] / neutronvpn / impl / src / main / java / org / opendaylight / netvirt / neutronvpn / NeutronPortChangeListener.java
1 /*
2  * Copyright © 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.base.Strings;
14 import com.google.common.util.concurrent.ListenableFuture;
15 import com.google.gson.Gson;
16 import com.google.gson.JsonArray;
17 import com.google.gson.JsonElement;
18 import com.google.gson.JsonObject;
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.HashMap;
22 import java.util.HashSet;
23 import java.util.List;
24 import java.util.Locale;
25 import java.util.Map;
26 import java.util.Set;
27 import java.util.stream.Collectors;
28 import javax.annotation.PostConstruct;
29 import javax.inject.Singleton;
30 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
31 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
32 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
33 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
34 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
35 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
36 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
37 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
38 import org.opendaylight.genius.mdsalutil.MDSALUtil;
39 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
40 import org.opendaylight.netvirt.elanmanager.api.IElanService;
41 import org.opendaylight.netvirt.neutronvpn.api.enums.IpVersionChoice;
42 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
43 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAcl;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAclBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceKey;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.elan._interface.StaticMacEntries;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.binding.rev150712.PortBindingExtension;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.hostconfig.rev150712.hostconfig.attributes.hostconfigs.Hostconfig;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
71 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
72 import org.slf4j.Logger;
73 import org.slf4j.LoggerFactory;
74
75 @Singleton
76 public class NeutronPortChangeListener extends AsyncDataTreeChangeListenerBase<Port, NeutronPortChangeListener> {
77     private static final Logger LOG = LoggerFactory.getLogger(NeutronPortChangeListener.class);
78     private final DataBroker dataBroker;
79     private final ManagedNewTransactionRunner txRunner;
80     private final NeutronvpnManager nvpnManager;
81     private final NeutronvpnNatManager nvpnNatManager;
82     private final NeutronSubnetGwMacResolver gwMacResolver;
83     private final IElanService elanService;
84     private final JobCoordinator jobCoordinator;
85     private final NeutronvpnUtils neutronvpnUtils;
86     private final HostConfigCache hostConfigCache;
87
88     public NeutronPortChangeListener(final DataBroker dataBroker,
89                                      final NeutronvpnManager neutronvpnManager,
90                                      final NeutronvpnNatManager neutronvpnNatManager,
91                                      final NeutronSubnetGwMacResolver gwMacResolver,
92                                      final IElanService elanService,
93                                      final JobCoordinator jobCoordinator,
94                                      final NeutronvpnUtils neutronvpnUtils,
95                                      final HostConfigCache hostConfigCache) {
96         super(Port.class, NeutronPortChangeListener.class);
97         this.dataBroker = dataBroker;
98         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
99         nvpnManager = neutronvpnManager;
100         nvpnNatManager = neutronvpnNatManager;
101         this.gwMacResolver = gwMacResolver;
102         this.elanService = elanService;
103         this.jobCoordinator = jobCoordinator;
104         this.neutronvpnUtils = neutronvpnUtils;
105         this.hostConfigCache = hostConfigCache;
106     }
107
108     @Override
109     @PostConstruct
110     public void init() {
111         LOG.info("{} init", getClass().getSimpleName());
112         registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
113     }
114
115     @Override
116     protected InstanceIdentifier<Port> getWildCardPath() {
117         return InstanceIdentifier.create(Neutron.class).child(Ports.class).child(Port.class);
118     }
119
120     @Override
121     protected NeutronPortChangeListener getDataTreeChangeListener() {
122         return NeutronPortChangeListener.this;
123     }
124
125
126     @Override
127     protected void add(InstanceIdentifier<Port> identifier, Port input) {
128         String portName = input.getUuid().getValue();
129         LOG.trace("Adding Port : key: {}, value={}", identifier, input);
130         Network network = neutronvpnUtils.getNeutronNetwork(input.getNetworkId());
131         if (network == null || !NeutronvpnUtils.isNetworkTypeSupported(network)) {
132             LOG.warn("neutron vpn received a port add() for a network without a provider extension augmentation "
133                             + "or with an unsupported network type for the port {} which is part of network {}",
134                     portName, network);
135             return;
136         }
137         neutronvpnUtils.addToPortCache(input);
138         String portStatus = NeutronUtils.PORT_STATUS_DOWN;
139         if (!Strings.isNullOrEmpty(input.getDeviceOwner()) && !Strings.isNullOrEmpty(input.getDeviceId())) {
140             if (input.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF)) {
141                 handleRouterInterfaceAdded(input);
142                 NeutronUtils.createPortStatus(input.getUuid().getValue(), NeutronUtils.PORT_STATUS_ACTIVE, dataBroker);
143                 return;
144             }
145             if (NeutronConstants.DEVICE_OWNER_GATEWAY_INF.equals(input.getDeviceOwner())) {
146                 handleRouterGatewayUpdated(input);
147                 portStatus = NeutronUtils.PORT_STATUS_ACTIVE;
148             } else if (NeutronConstants.DEVICE_OWNER_FLOATING_IP.equals(input.getDeviceOwner())) {
149                 handleFloatingIpPortUpdated(null, input);
150                 portStatus = NeutronUtils.PORT_STATUS_ACTIVE;
151             }
152         }
153         // Switchdev ports need to be bounded to a host before creation
154         // in order to validate the supported vnic types from the hostconfig
155         if (input.getFixedIps() != null
156             && !input.getFixedIps().isEmpty()
157             && !(isPortTypeSwitchdev(input) && !isPortBound(input))) {
158             handleNeutronPortCreated(input);
159         }
160         NeutronUtils.createPortStatus(input.getUuid().getValue(), portStatus, dataBroker);
161     }
162
163     @Override
164     protected void remove(InstanceIdentifier<Port> identifier, Port input) {
165         LOG.trace("Removing Port : key: {}, value={}", identifier, input);
166         Network network = neutronvpnUtils.getNeutronNetwork(input.getNetworkId());
167         if (network == null || !NeutronvpnUtils.isNetworkTypeSupported(network)) {
168             String portName = input.getUuid().getValue();
169             LOG.warn("neutron vpn received a port remove() for a network without a provider extension augmentation "
170                             + "or with an unsupported network type for the port {} which is part of network {}",
171                     portName, network);
172             return;
173         }
174         neutronvpnUtils.removeFromPortCache(input);
175         NeutronUtils.deletePortStatus(input.getUuid().getValue(), dataBroker);
176
177         if (!Strings.isNullOrEmpty(input.getDeviceOwner()) && !Strings.isNullOrEmpty(input.getDeviceId())) {
178             if (input.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF)) {
179                 handleRouterInterfaceRemoved(input);
180                 /* nothing else to do here */
181                 return;
182             } else if (NeutronConstants.DEVICE_OWNER_GATEWAY_INF.equals(input.getDeviceOwner())
183                     || NeutronConstants.DEVICE_OWNER_FLOATING_IP.equals(input.getDeviceOwner())) {
184                 elanService.removeKnownL3DmacAddress(input.getMacAddress().getValue(), input.getNetworkId().getValue());
185             }
186         }
187         if (input.getFixedIps() != null) {
188             handleNeutronPortDeleted(input);
189         }
190     }
191
192     @Override
193     protected void update(InstanceIdentifier<Port> identifier, Port original, Port update) {
194         // Switchdev ports need to be bounded to a host before creation
195         // in order to validate the supported vnic types from the hostconfig
196         if (isPortTypeSwitchdev(original)
197             && !isPortBound(original)
198             && isPortBound(update)) {
199             handleNeutronPortCreated(update);
200         }
201         final String portName = update.getUuid().getValue();
202         Network network = neutronvpnUtils.getNeutronNetwork(update.getNetworkId());
203         LOG.info("Update port {} from network {}", portName, update.getNetworkId().toString());
204         if (network == null || !NeutronvpnUtils.isNetworkTypeSupported(network)) {
205             LOG.error("neutron vpn received a port update() for a network without a provider extension augmentation "
206                     + "or with an unsupported network type for the port {} which is part of network {}",
207                     portName, network);
208             return;
209         }
210         neutronvpnUtils.addToPortCache(update);
211
212         if ((Strings.isNullOrEmpty(original.getDeviceOwner()) || Strings.isNullOrEmpty(original.getDeviceId())
213                 || NeutronConstants.FLOATING_IP_DEVICE_ID_PENDING.equalsIgnoreCase(original.getDeviceId()))
214                 && !Strings.isNullOrEmpty(update.getDeviceOwner()) && !Strings.isNullOrEmpty(update.getDeviceId())) {
215             if (update.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF)) {
216                 handleRouterInterfaceAdded(update);
217                 return;
218             }
219             if (NeutronConstants.DEVICE_OWNER_GATEWAY_INF.equals(update.getDeviceOwner())) {
220                 handleRouterGatewayUpdated(update);
221             } else if (NeutronConstants.DEVICE_OWNER_FLOATING_IP.equals(update.getDeviceOwner())) {
222                 handleFloatingIpPortUpdated(original, update);
223             }
224         } else {
225             Set<FixedIps> oldIPs = getFixedIpSet(original.getFixedIps());
226             Set<FixedIps> newIPs = getFixedIpSet(update.getFixedIps());
227             if (!oldIPs.equals(newIPs)) {
228                 handleNeutronPortUpdated(original, update);
229             }
230         }
231
232         // check if port security enabled/disabled as part of port update
233         boolean origSecurityEnabled = NeutronvpnUtils.getPortSecurityEnabled(original);
234         boolean updatedSecurityEnabled = NeutronvpnUtils.getPortSecurityEnabled(update);
235
236         if (origSecurityEnabled || updatedSecurityEnabled) {
237             InstanceIdentifier<Interface>  interfaceIdentifier = NeutronvpnUtils.buildVlanInterfaceIdentifier(portName);
238             jobCoordinator.enqueueJob("PORT- " + portName, () -> {
239                 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
240                 try {
241                     Optional<Interface> optionalInf =
242                             SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
243                                     interfaceIdentifier);
244                     if (optionalInf.isPresent()) {
245                         InterfaceBuilder interfaceBuilder = new InterfaceBuilder(optionalInf.get());
246                         InterfaceAcl infAcl = handlePortSecurityUpdated(original, update,
247                                 origSecurityEnabled, updatedSecurityEnabled, interfaceBuilder).build();
248                         interfaceBuilder.addAugmentation(InterfaceAcl.class, infAcl);
249                         LOG.info("update: Of-port-interface updation for port {}", portName);
250                         // Update OFPort interface for this neutron port
251                         wrtConfigTxn.put(LogicalDatastoreType.CONFIGURATION, interfaceIdentifier,
252                                 interfaceBuilder.build());
253                     } else {
254                         LOG.warn("update: Interface {} is not present", portName);
255                     }
256                 } catch (ReadFailedException e) {
257                     LOG.error("update: Failed to update interface {}", portName, e);
258                 }
259                 List<ListenableFuture<Void>> futures = new ArrayList<>();
260                 futures.add(wrtConfigTxn.submit());
261                 return futures;
262             });
263         }
264     }
265
266     private void handleFloatingIpPortUpdated(Port original, Port update) {
267         if ((original == null || original.getDeviceId().equals(NeutronConstants.FLOATING_IP_DEVICE_ID_PENDING))
268             && !update.getDeviceId().equals(NeutronConstants.FLOATING_IP_DEVICE_ID_PENDING)) {
269             // populate floating-ip uuid and floating-ip port attributes (uuid, mac and subnet id for the ONLY
270             // fixed IP) to be used by NAT, depopulated in NATService once mac is retrieved in the removal path
271             addToFloatingIpPortInfo(new Uuid(update.getDeviceId()), update.getUuid(), update.getFixedIps().get(0)
272                     .getSubnetId(), update.getMacAddress().getValue());
273             elanService.addKnownL3DmacAddress(update.getMacAddress().getValue(), update.getNetworkId().getValue());
274         }
275     }
276
277     private void handleRouterInterfaceAdded(Port routerPort) {
278         if (routerPort.getDeviceId() != null) {
279             Uuid routerId = new Uuid(routerPort.getDeviceId());
280             Uuid infNetworkId = routerPort.getNetworkId();
281             Uuid existingVpnId = neutronvpnUtils.getVpnForNetwork(infNetworkId);
282
283             elanService.addKnownL3DmacAddress(routerPort.getMacAddress().getValue(), infNetworkId.getValue());
284             if (existingVpnId == null) {
285                 Set<Uuid> listVpnIds = new HashSet<>();
286                 Uuid vpnId = neutronvpnUtils.getVpnForRouter(routerId, true);
287                 if (vpnId == null) {
288                     vpnId = routerId;
289                 }
290                 listVpnIds.add(vpnId);
291                 Uuid internetVpnId = neutronvpnUtils.getInternetvpnUuidBoundToRouterId(routerId);
292                 List<Subnetmap> subnetMapList = new ArrayList<>();
293                 List<FixedIps> portIps = routerPort.getFixedIps();
294                 boolean portIsIpv6 = false;
295                 for (FixedIps portIP : portIps) {
296                     // NOTE:  Please donot change the order of calls to updateSubnetNodeWithFixedIP
297                     // and addSubnetToVpn here
298                     if (internetVpnId != null
299                         && portIP.getIpAddress().getIpv6Address() != null) {
300                         portIsIpv6 = true;
301                     }
302                     String ipValue = String.valueOf(portIP.getIpAddress().getValue());
303                     Uuid subnetId = portIP.getSubnetId();
304                     nvpnManager.updateSubnetNodeWithFixedIp(subnetId, routerId,
305                             routerPort.getUuid(), ipValue, routerPort.getMacAddress().getValue(), vpnId);
306                     Subnetmap sn = neutronvpnUtils.getSubnetmap(subnetId);
307                     subnetMapList.add(sn);
308                 }
309                 if (portIsIpv6) {
310                     listVpnIds.add(internetVpnId);
311                     if (neutronvpnUtils.shouldVpnHandleIpVersionChoiceChangeToAdd(
312                                      IpVersionChoice.IPV6, internetVpnId)) {
313                         neutronvpnUtils.updateVpnInstanceWithIpFamily(internetVpnId.getValue(),
314                                                                      IpVersionChoice.IPV6, true);
315                         neutronvpnUtils.updateVpnInstanceWithFallback(internetVpnId.getValue(), true);
316                     }
317                 }
318                 if (! subnetMapList.isEmpty()) {
319                     nvpnManager.createVpnInterface(listVpnIds, routerPort, null);
320                 }
321                 for (FixedIps portIP : routerPort.getFixedIps()) {
322                     String ipValue = String.valueOf(portIP.getIpAddress().getValue());
323                     IpVersionChoice version = neutronvpnUtils.getIpVersionFromString(ipValue);
324                     if (neutronvpnUtils.shouldVpnHandleIpVersionChoiceChangeToAdd(version, vpnId)) {
325                         neutronvpnUtils.updateVpnInstanceWithIpFamily(vpnId.getValue(),
326                                version, true);
327                     }
328                     if (version.isIpVersionChosen(IpVersionChoice.IPV4)) {
329                         nvpnManager.addSubnetToVpn(vpnId, portIP.getSubnetId(),
330                                                         null /* internet-vpn-id */);
331                     } else {
332                         nvpnManager.addSubnetToVpn(vpnId, portIP.getSubnetId(), internetVpnId);
333                     }
334                     LOG.trace("NeutronPortChangeListener Add Subnet Gateway IP {} MAC {} Interface {} VPN {}",
335                             ipValue, routerPort.getMacAddress(),
336                             routerPort.getUuid().getValue(), vpnId.getValue());
337                 }
338                 nvpnManager.addToNeutronRouterInterfacesMap(routerId, routerPort.getUuid().getValue());
339                 nvpnNatManager.handleSubnetsForExternalRouter(routerId);
340                 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
341                 String portInterfaceName = createOfPortInterface(routerPort, wrtConfigTxn);
342                 createElanInterface(routerPort, portInterfaceName, wrtConfigTxn);
343                 wrtConfigTxn.submit();
344             } else {
345                 LOG.error("Neutron network {} corresponding to router interface port {} for neutron router {}"
346                     + " already associated to VPN {}", infNetworkId.getValue(), routerPort.getUuid().getValue(),
347                     routerId.getValue(), existingVpnId.getValue());
348             }
349         }
350     }
351
352     private void handleRouterInterfaceRemoved(Port routerPort) {
353         if (routerPort.getDeviceId() != null) {
354             Uuid routerId = new Uuid(routerPort.getDeviceId());
355             Uuid infNetworkId = routerPort.getNetworkId();
356             elanService.removeKnownL3DmacAddress(routerPort.getMacAddress().getValue(), infNetworkId.getValue());
357             Uuid vpnId = neutronvpnUtils.getVpnForRouter(routerId, true);
358             if (vpnId == null) {
359                 vpnId = routerId;
360             }
361             List<FixedIps> portIps = routerPort.getFixedIps();
362             boolean vpnInstanceInternetIpVersionRemoved = false;
363             Uuid vpnInstanceInternetUuid = null;
364             for (FixedIps portIP : portIps) {
365                 // Internet VPN : flush InternetVPN first
366                 Uuid subnetId = portIP.getSubnetId();
367                 Subnetmap sn = neutronvpnUtils.getSubnetmap(subnetId);
368                 if (sn != null && sn.getInternetVpnId() != null) {
369                     if (neutronvpnUtils.shouldVpnHandleIpVersionChangeToRemove(sn, sn.getInternetVpnId())) {
370                         vpnInstanceInternetIpVersionRemoved = true;
371                         vpnInstanceInternetUuid = sn.getInternetVpnId();
372                     }
373                     nvpnManager.updateVpnInternetForSubnet(sn, sn.getInternetVpnId(), false);
374                 }
375             }
376             /* Remove ping responder for router interfaces
377              *  A router interface reference in a VPN will have to be removed before the host interface references
378              * for that subnet in the VPN are removed. This is to ensure that the FIB Entry of the router interface
379              *  is not the last entry to be removed for that subnet in the VPN.
380              *  If router interface FIB entry is the last to be removed for a subnet in a VPN , then all the host
381              *  interface references in the vpn will already have been cleared, which will cause failures in
382              *  cleanup of router interface flows*/
383             nvpnManager.deleteVpnInterface(routerPort.getUuid().getValue(),
384                                            null /* vpn-id */, null /* wrtConfigTxn*/);
385             // update RouterInterfaces map
386             WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
387             boolean vpnInstanceIpVersionRemoved = false;
388             IpVersionChoice vpnInstanceIpVersionToRemove = IpVersionChoice.UNDEFINED;
389             for (FixedIps portIP : portIps) {
390                 Subnetmap sn = neutronvpnUtils.getSubnetmap(portIP.getSubnetId());
391                 // router Port have either IPv4 or IPv6, never both
392                 if (neutronvpnUtils.shouldVpnHandleIpVersionChangeToRemove(sn, vpnId)) {
393                     vpnInstanceIpVersionRemoved = true;
394                     vpnInstanceIpVersionToRemove = neutronvpnUtils.getIpVersionFromString(sn.getSubnetIp());
395                 }
396                 String ipValue = String.valueOf(portIP.getIpAddress().getValue());
397                 neutronvpnUtils.removeVpnPortFixedIpToPort(vpnId.getValue(), ipValue, wrtConfigTxn);
398                 // NOTE:  Please donot change the order of calls to removeSubnetFromVpn and
399                 // and updateSubnetNodeWithFixedIP
400                 nvpnManager.removeSubnetFromVpn(vpnId, portIP.getSubnetId(), sn != null ? sn.getInternetVpnId() : null);
401                 nvpnManager.updateSubnetNodeWithFixedIp(portIP.getSubnetId(), null, null, null, null, null);
402             }
403             nvpnManager.removeFromNeutronRouterInterfacesMap(routerId, routerPort.getUuid().getValue());
404             deleteElanInterface(routerPort.getUuid().getValue(), wrtConfigTxn);
405             deleteOfPortInterface(routerPort, wrtConfigTxn);
406             wrtConfigTxn.submit();
407             nvpnNatManager.handleSubnetsForExternalRouter(routerId);
408             if (vpnInstanceIpVersionRemoved) {
409                 neutronvpnUtils.updateVpnInstanceWithIpFamily(vpnId.getValue(), vpnInstanceIpVersionToRemove,
410                           false);
411             }
412             if (vpnInstanceInternetIpVersionRemoved) {
413                 neutronvpnUtils.updateVpnInstanceWithIpFamily(vpnInstanceInternetUuid.getValue(),
414                                                              IpVersionChoice.IPV6, false);
415                 neutronvpnUtils.updateVpnInstanceWithFallback(vpnInstanceInternetUuid.getValue(), false);
416             }
417         }
418     }
419
420     private void handleRouterGatewayUpdated(Port routerGwPort) {
421         Uuid routerId = new Uuid(routerGwPort.getDeviceId());
422         Uuid networkId = routerGwPort.getNetworkId();
423         Network network = neutronvpnUtils.getNeutronNetwork(networkId);
424         if (network == null) {
425             return;
426         }
427         boolean isExternal = neutronvpnUtils.getIsExternal(network);
428         if (isExternal) {
429             Uuid vpnInternetId = neutronvpnUtils.getVpnForNetwork(networkId);
430             if (vpnInternetId != null) {
431                 List<Subnetmap> snList = neutronvpnUtils.getNeutronRouterSubnetMaps(routerId);
432                 for (Subnetmap sn : snList) {
433                     if (sn.getNetworkId() == networkId) {
434                         continue;
435                     }
436                     if (neutronvpnUtils.getIpVersionFromString(sn.getSubnetIp()) != IpVersionChoice.IPV6) {
437                         continue;
438                     }
439                     nvpnManager.addSubnetToVpn(null, sn.getId(), vpnInternetId);
440                 }
441             }
442         }
443         elanService.addKnownL3DmacAddress(routerGwPort.getMacAddress().getValue(), networkId.getValue());
444
445         Router router = neutronvpnUtils.getNeutronRouter(routerId);
446         if (router == null) {
447             LOG.warn("No router found for router GW port {} for router {}", routerGwPort.getUuid().getValue(),
448                     routerId.getValue());
449             return;
450         }
451         gwMacResolver.sendArpRequestsToExtGateways(router);
452
453         setExternalGwMac(routerGwPort, routerId);
454     }
455
456     private void setExternalGwMac(Port routerGwPort, Uuid routerId) {
457         // During full-sync networking-odl syncs routers before ports. As such,
458         // the MAC of the router's gw port is not available to be set when the
459         // router is written. We catch that here.
460         InstanceIdentifier<Routers> routersId = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
461         Optional<Routers> optionalRouter = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, routersId);
462         if (!optionalRouter.isPresent()) {
463             return;
464         }
465
466         Routers extRouters = optionalRouter.get();
467         if (extRouters.getExtGwMacAddress() != null) {
468             return;
469         }
470
471         RoutersBuilder builder = new RoutersBuilder(extRouters);
472         builder.setExtGwMacAddress(routerGwPort.getMacAddress().getValue());
473         MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, routersId, builder.build());
474     }
475
476     private String getPortHostId(final Port port) {
477         if (port != null) {
478             PortBindingExtension portBinding = port.getAugmentation(PortBindingExtension.class);
479             if (portBinding != null) {
480                 return portBinding.getHostId();
481             }
482         }
483         return null;
484     }
485
486     private Hostconfig getHostConfig(final Port port) {
487         String hostId = getPortHostId(port);
488         if (hostId == null) {
489             return null;
490         }
491         Optional<Hostconfig> hostConfig;
492         try {
493             hostConfig = this.hostConfigCache.get(hostId);
494         } catch (ReadFailedException e) {
495             LOG.error("failed to read host config from host {}", hostId, e);
496             return null;
497         }
498         return hostConfig.isPresent() ? hostConfig.get() : null;
499     }
500
501     private boolean isPortBound(final Port port) {
502         String hostId = getPortHostId(port);
503         return hostId != null && !hostId.isEmpty();
504     }
505
506     private boolean isPortVnicTypeDirect(Port port) {
507         PortBindingExtension portBinding = port.getAugmentation(PortBindingExtension.class);
508         if (portBinding == null || portBinding.getVnicType() == null) {
509             // By default, VNIC_TYPE is NORMAL
510             return false;
511         }
512         String vnicType = portBinding.getVnicType().trim().toLowerCase(Locale.getDefault());
513         return vnicType.equals(NeutronConstants.VNIC_TYPE_DIRECT);
514     }
515
516     private boolean isSupportedVnicTypeByHost(final Port port, final String vnicType) {
517         Hostconfig hostConfig = getHostConfig(port);
518         String supportStr = String.format("\"vnic_type\": \"%s\"", vnicType);
519         if (hostConfig != null && hostConfig.getConfig().contains(supportStr)) {
520             return true;
521         }
522         return false;
523     }
524
525     private Map<String, JsonElement> unmarshal(final String profile) {
526         if (null == profile) {
527             return null;
528         }
529         Gson gson = new Gson();
530         JsonObject jsonObject = gson.fromJson(profile, JsonObject.class);
531         Map<String, JsonElement> map = new HashMap();
532         for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
533             map.put(entry.getKey(), entry.getValue());
534         }
535         return map;
536     }
537
538     private boolean isPortTypeSwitchdev(final Port port) {
539         if (!isPortVnicTypeDirect(port)) {
540             return false;
541         }
542
543         PortBindingExtension portBinding = port.getAugmentation(PortBindingExtension.class);
544         String profile = portBinding.getProfile();
545         if (profile == null || profile.isEmpty()) {
546             LOG.debug("Port {} has no binding:profile values", port.getUuid());
547             return false;
548         }
549
550         Map<String, JsonElement> mapProfile = unmarshal(profile);
551         JsonElement capabilities = mapProfile.get(NeutronConstants.BINDING_PROFILE_CAPABILITIES);
552         LOG.debug("Port {} capabilities: {}", port.getUuid(), capabilities);
553         if (capabilities == null || !capabilities.isJsonArray()) {
554             LOG.debug("binding profile capabilities not in array format: {}", capabilities);
555             return false;
556         }
557
558         JsonArray capabilitiesArray = capabilities.getAsJsonArray();
559         Gson gson = new Gson();
560         JsonElement switchdevElement = gson.fromJson(NeutronConstants.SWITCHDEV, JsonElement.class);
561         return capabilitiesArray.contains(switchdevElement);
562     }
563
564
565     private void handleNeutronPortCreated(final Port port) {
566         final String portName = port.getUuid().getValue();
567         final Uuid portId = port.getUuid();
568         final List<FixedIps> portIpAddrsList = port.getFixedIps();
569         if (NeutronConstants.IS_ODL_DHCP_PORT.test(port)) {
570             return;
571         }
572         jobCoordinator.enqueueJob("PORT- " + portName, () -> {
573             // add direct port to subnetMaps config DS
574             if (!(NeutronUtils.isPortVnicTypeNormal(port)
575                 || (isPortTypeSwitchdev(port)
576                 && isSupportedVnicTypeByHost(port, NeutronConstants.VNIC_TYPE_DIRECT)))) {
577                 for (FixedIps ip: portIpAddrsList) {
578                     nvpnManager.updateSubnetmapNodeWithPorts(ip.getSubnetId(), null, portId);
579                 }
580                 LOG.info("Port {} is not a NORMAL VNIC Type port; OF Port interfaces are not created", portName);
581                 return Collections.emptyList();
582             }
583             return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
584                 LOG.info("Of-port-interface creation for port {}", portName);
585                 // Create of-port interface for this neutron port
586                 String portInterfaceName = createOfPortInterface(port, tx);
587                 LOG.debug("Creating ELAN Interface for port {}", portName);
588                 createElanInterface(port, portInterfaceName, tx);
589                 Set<Uuid> vpnIdList =  new HashSet<>();
590                 Set<Uuid> routerIds = new HashSet<>();
591                 for (FixedIps ip: portIpAddrsList) {
592                     Subnetmap subnetMap = nvpnManager.updateSubnetmapNodeWithPorts(ip.getSubnetId(), portId, null);
593                     if (subnetMap != null && subnetMap.getInternetVpnId() != null) {
594                         if (!vpnIdList.contains(subnetMap.getInternetVpnId())) {
595                             vpnIdList.add(subnetMap.getInternetVpnId());
596                         }
597                     }
598                     if (subnetMap != null && subnetMap.getVpnId() != null) {
599                         // can't use NeutronvpnUtils.getVpnForNetwork to optimise here, because it gives BGPVPN id
600                         // obtained subnetMaps belongs to one network => vpnId must be the same for each port Ip
601                         Uuid vpnId = subnetMap.getVpnId();
602                         if (vpnId != null) {
603                             vpnIdList.add(vpnId);
604                         }
605                     }
606                     if (subnetMap != null && subnetMap.getRouterId() != null) {
607                         routerIds.add(subnetMap.getRouterId());
608                     }
609                 }
610                 if (!vpnIdList.isEmpty()) {
611                     // create new vpn-interface for neutron port
612                     LOG.debug("handleNeutronPortCreated: Adding VPN Interface for port {} from network {}", portName,
613                             port.getNetworkId().toString());
614                     nvpnManager.createVpnInterface(vpnIdList, port, tx);
615                     if (!routerIds.isEmpty()) {
616                         for (Uuid routerId : routerIds) {
617                             nvpnManager.addToNeutronRouterInterfacesMap(routerId,port.getUuid().getValue());
618                         }
619                     }
620                 }
621             }));
622         });
623     }
624
625     private void handleNeutronPortDeleted(final Port port) {
626         final String portName = port.getUuid().getValue();
627         final Uuid portId = port.getUuid();
628         final List<FixedIps> portIpsList = port.getFixedIps();
629         jobCoordinator.enqueueJob("PORT- " + portName, () -> {
630             WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
631             List<ListenableFuture<Void>> futures = new ArrayList<>();
632             if (!NeutronUtils.isPortVnicTypeNormal(port)) {
633                 for (FixedIps ip: portIpsList) {
634                     // remove direct port from subnetMaps config DS
635                     nvpnManager.removePortsFromSubnetmapNode(ip.getSubnetId(), null, portId);
636                 }
637                 LOG.info("Port {} is not a NORMAL VNIC Type port; OF Port interfaces are not created", portName);
638                 return futures;
639             }
640             Uuid vpnId = null;
641             Set<Uuid> routerIds = new HashSet<>();
642             Uuid internetVpnId = null;
643             for (FixedIps ip: portIpsList) {
644                 Subnetmap subnetMap = nvpnManager.removePortsFromSubnetmapNode(ip.getSubnetId(), portId, null);
645                 if (subnetMap == null) {
646                     continue;
647                 }
648                 if (subnetMap.getVpnId() != null) {
649                     // can't use NeutronvpnUtils.getVpnForNetwork to optimise here, because it gives BGPVPN id
650                     // obtained subnetMaps belongs to one network => vpnId must be the same for each port Ip
651                     vpnId = subnetMap.getVpnId();
652                 }
653                 if (subnetMap.getRouterId() != null) {
654                     routerIds.add(subnetMap.getRouterId());
655                 }
656                 internetVpnId = subnetMap.getInternetVpnId();
657             }
658             if (vpnId != null || internetVpnId != null) {
659                 // remove vpn-interface for this neutron port
660                 LOG.debug("removing VPN Interface for port {}", portName);
661                 if (!routerIds.isEmpty()) {
662                     for (Uuid routerId : routerIds) {
663                         nvpnManager.removeFromNeutronRouterInterfacesMap(routerId, portName);
664                     }
665                 }
666                 nvpnManager.deleteVpnInterface(portName, null /* vpn-id */, wrtConfigTxn);
667             }
668             // Remove of-port interface for this neutron port
669             // ELAN interface is also implicitly deleted as part of this operation
670             LOG.debug("Of-port-interface removal for port {}", portName);
671             deleteOfPortInterface(port, wrtConfigTxn);
672             //dissociate fixedIP from floatingIP if associated
673             nvpnManager.dissociatefixedIPFromFloatingIP(port.getUuid().getValue());
674             futures.add(wrtConfigTxn.submit());
675             return futures;
676         });
677     }
678
679
680     private void handleNeutronPortUpdated(final Port portoriginal, final Port portupdate) {
681         final List<FixedIps> portoriginalIps = portoriginal.getFixedIps();
682         final List<FixedIps> portupdateIps = portupdate.getFixedIps();
683         if (portoriginalIps == null || portoriginalIps.isEmpty()) {
684             handleNeutronPortCreated(portupdate);
685             return;
686         }
687
688         if (portupdateIps == null || portupdateIps.isEmpty()) {
689             LOG.info("Ignoring portUpdate (fixed_ip removal) for port {} as this case is handled "
690                       + "during subnet deletion event.", portupdate.getUuid().getValue());
691             return;
692         }
693         jobCoordinator.enqueueJob("PORT- " + portupdate.getUuid().getValue(),
694             () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
695                 final List<Uuid> originalSnMapsIds = portoriginalIps.stream().map(FixedIps::getSubnetId)
696                         .collect(Collectors.toList());
697                 final List<Uuid> updateSnMapsIds = portupdateIps.stream().map(FixedIps::getSubnetId)
698                         .collect(Collectors.toList());
699                 Set<Uuid> originalRouterIds = new HashSet<>();
700                 Set<Uuid> oldVpnIds = new HashSet<Uuid>();
701                 Uuid oldRouterId = null;
702                 for (Uuid snId: originalSnMapsIds) {
703                     if (!updateSnMapsIds.remove(snId)) {
704                         // snId was present in originalSnMapsIds, but not in updateSnMapsIds
705                         Subnetmap subnetMapOld = nvpnManager.removePortsFromSubnetmapNode(snId, portoriginal.getUuid(),
706                                 null);
707                         if (subnetMapOld != null && subnetMapOld.getVpnId() != null) {
708                             oldVpnIds.add(subnetMapOld.getVpnId());
709                         }
710                         if (subnetMapOld != null && subnetMapOld.getInternetVpnId() != null) {
711                             oldVpnIds.add(subnetMapOld.getInternetVpnId());
712                         }
713                         if (subnetMapOld != null && subnetMapOld.getRouterId() != null) {
714                             originalRouterIds.add(subnetMapOld.getRouterId());
715                         }
716                     }
717                 }
718                 Set<Uuid> newVpnIds = new HashSet();
719                 Set<Uuid> newRouterIds = new HashSet<>();
720                 for (Uuid snId: updateSnMapsIds) {
721                     Subnetmap subnetMapNew = nvpnManager.updateSubnetmapNodeWithPorts(snId, portupdate.getUuid(), null);
722                     if (subnetMapNew != null) {
723                         if (subnetMapNew.getVpnId() != null) {
724                             newVpnIds.add(subnetMapNew.getVpnId());
725                         }
726                         if (subnetMapNew.getInternetVpnId() != null) {
727                             newVpnIds.add(subnetMapNew.getInternetVpnId());
728                         }
729                         if (subnetMapNew.getRouterId() != null) {
730                             newRouterIds.add(subnetMapNew.getRouterId());
731                         }
732                     }
733                 }
734                 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
735                 if (!oldVpnIds.isEmpty()) {
736                     LOG.info("removing VPN Interface for port {}", portoriginal.getUuid().getValue());
737                     if (!originalRouterIds.isEmpty()) {
738                         for (Uuid routerId : originalRouterIds) {
739                             nvpnManager.removeFromNeutronRouterInterfacesMap(routerId,
740                                     portoriginal.getUuid().getValue());
741                         }
742                     }
743                     nvpnManager.deleteVpnInterface(portoriginal.getUuid().getValue(),
744                                                    null /* vpn-id */, wrtConfigTxn);
745                 }
746                 if (!newVpnIds.isEmpty()) {
747                     LOG.info("Adding VPN Interface for port {}", portupdate.getUuid().getValue());
748                     nvpnManager.createVpnInterface(newVpnIds, portupdate, wrtConfigTxn);
749                     if (!newRouterIds.isEmpty()) {
750                         for (Uuid routerId : newRouterIds) {
751                             nvpnManager.addToNeutronRouterInterfacesMap(routerId,portupdate.getUuid().getValue());
752                         }
753                     }
754                 }
755             })));
756     }
757
758     private static InterfaceAclBuilder handlePortSecurityUpdated(Port portOriginal,
759             Port portUpdated, boolean origSecurityEnabled, boolean updatedSecurityEnabled,
760             InterfaceBuilder interfaceBuilder) {
761         InterfaceAclBuilder interfaceAclBuilder = null;
762         if (origSecurityEnabled != updatedSecurityEnabled) {
763             interfaceAclBuilder = new InterfaceAclBuilder();
764             interfaceAclBuilder.setPortSecurityEnabled(updatedSecurityEnabled);
765             if (updatedSecurityEnabled) {
766                 // Handle security group enabled
767                 NeutronvpnUtils.populateInterfaceAclBuilder(interfaceAclBuilder, portUpdated);
768             } else {
769                 // Handle security group disabled
770                 interfaceAclBuilder.setSecurityGroups(new ArrayList<>());
771                 interfaceAclBuilder.setAllowedAddressPairs(new ArrayList<>());
772             }
773         } else {
774             if (updatedSecurityEnabled) {
775                 // handle SG add/delete delta
776                 InterfaceAcl interfaceAcl = interfaceBuilder.getAugmentation(InterfaceAcl.class);
777                 interfaceAclBuilder = new InterfaceAclBuilder(interfaceAcl);
778                 interfaceAclBuilder.setSecurityGroups(
779                         NeutronvpnUtils.getUpdatedSecurityGroups(interfaceAcl.getSecurityGroups(),
780                                 portOriginal.getSecurityGroups(), portUpdated.getSecurityGroups()));
781                 List<AllowedAddressPairs> updatedAddressPairs = NeutronvpnUtils.getUpdatedAllowedAddressPairs(
782                         interfaceAcl.getAllowedAddressPairs(), portOriginal.getAllowedAddressPairs(),
783                         portUpdated.getAllowedAddressPairs());
784                 interfaceAclBuilder.setAllowedAddressPairs(NeutronvpnUtils.getAllowedAddressPairsForFixedIps(
785                         updatedAddressPairs, portOriginal.getMacAddress(), portOriginal.getFixedIps(),
786                         portUpdated.getFixedIps()));
787             }
788         }
789         return interfaceAclBuilder;
790     }
791
792     private String createOfPortInterface(Port port, WriteTransaction wrtConfigTxn) {
793         Interface inf = createInterface(port);
794         String infName = inf.getName();
795
796         InstanceIdentifier<Interface> interfaceIdentifier = NeutronvpnUtils.buildVlanInterfaceIdentifier(infName);
797         try {
798             Optional<Interface> optionalInf =
799                     SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
800                             interfaceIdentifier);
801             if (!optionalInf.isPresent()) {
802                 wrtConfigTxn.put(LogicalDatastoreType.CONFIGURATION, interfaceIdentifier, inf);
803             } else {
804                 LOG.warn("Interface {} is already present", infName);
805             }
806         } catch (ReadFailedException e) {
807             LOG.error("failed to create interface {}", infName, e);
808         }
809         return infName;
810     }
811
812     private Interface createInterface(Port port) {
813         String interfaceName = port.getUuid().getValue();
814         IfL2vlan.L2vlanMode l2VlanMode = IfL2vlan.L2vlanMode.Trunk;
815         InterfaceBuilder interfaceBuilder = new InterfaceBuilder();
816         IfL2vlanBuilder ifL2vlanBuilder = new IfL2vlanBuilder();
817         ifL2vlanBuilder.setL2vlanMode(l2VlanMode);
818
819         interfaceBuilder.setEnabled(true).setName(interfaceName).setType(L2vlan.class)
820                 .addAugmentation(IfL2vlan.class, ifL2vlanBuilder.build());
821
822         if (NeutronvpnUtils.getPortSecurityEnabled(port)) {
823             InterfaceAclBuilder interfaceAclBuilder = new InterfaceAclBuilder();
824             interfaceAclBuilder.setPortSecurityEnabled(true);
825             NeutronvpnUtils.populateInterfaceAclBuilder(interfaceAclBuilder, port);
826             interfaceBuilder.addAugmentation(InterfaceAcl.class, interfaceAclBuilder.build());
827             neutronvpnUtils.populateSubnetIpPrefixes(port);
828         }
829         return interfaceBuilder.build();
830     }
831
832     private void deleteOfPortInterface(Port port, WriteTransaction wrtConfigTxn) {
833         String name = port.getUuid().getValue();
834         LOG.debug("Removing OFPort Interface {}", name);
835         InstanceIdentifier<Interface>  interfaceIdentifier = NeutronvpnUtils.buildVlanInterfaceIdentifier(name);
836         try {
837             Optional<Interface> optionalInf =
838                     SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
839                             interfaceIdentifier);
840             if (optionalInf.isPresent()) {
841                 wrtConfigTxn.delete(LogicalDatastoreType.CONFIGURATION, interfaceIdentifier);
842             } else {
843                 LOG.warn("deleteOfPortInterface: Interface {} is not present", name);
844             }
845         } catch (ReadFailedException e) {
846             LOG.error("deleteOfPortInterface: Failed to delete interface {}", name, e);
847         }
848     }
849
850     private void createElanInterface(Port port, String name, WriteTransaction wrtConfigTxn) {
851         String elanInstanceName = port.getNetworkId().getValue();
852         List<StaticMacEntries> staticMacEntries = NeutronvpnUtils.buildStaticMacEntry(port);
853
854         InstanceIdentifier<ElanInterface> id = InstanceIdentifier.builder(ElanInterfaces.class).child(ElanInterface
855                 .class, new ElanInterfaceKey(name)).build();
856         ElanInterface elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName)
857                 .setName(name).setStaticMacEntries(staticMacEntries).setKey(new ElanInterfaceKey(name)).build();
858         wrtConfigTxn.put(LogicalDatastoreType.CONFIGURATION, id, elanInterface);
859         LOG.debug("Creating new ELan Interface {}", elanInterface);
860     }
861
862     private void deleteElanInterface(String name, WriteTransaction wrtConfigTxn) {
863         InstanceIdentifier<ElanInterface> id = InstanceIdentifier.builder(ElanInterfaces.class).child(ElanInterface
864                 .class, new ElanInterfaceKey(name)).build();
865         wrtConfigTxn.delete(LogicalDatastoreType.CONFIGURATION, id);
866     }
867
868     // TODO Clean up the exception handling
869     @SuppressWarnings("checkstyle:IllegalCatch")
870     private void addToFloatingIpPortInfo(Uuid floatingIpId, Uuid floatingIpPortId, Uuid floatingIpPortSubnetId, String
871                                          floatingIpPortMacAddress) {
872         InstanceIdentifier id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
873         try {
874             FloatingIpIdToPortMappingBuilder floatingipIdToPortMacMappingBuilder = new
875                 FloatingIpIdToPortMappingBuilder().setKey(new FloatingIpIdToPortMappingKey(floatingIpId))
876                 .setFloatingIpId(floatingIpId).setFloatingIpPortId(floatingIpPortId)
877                 .setFloatingIpPortSubnetId(floatingIpPortSubnetId)
878                 .setFloatingIpPortMacAddress(floatingIpPortMacAddress);
879             LOG.debug("Creating floating IP UUID {} to Floating IP neutron port {} mapping in Floating IP"
880                 + " Port Info Config DS", floatingIpId.getValue(), floatingIpPortId.getValue());
881             MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id,
882                 floatingipIdToPortMacMappingBuilder.build());
883         } catch (Exception e) {
884             LOG.error("Creating floating IP UUID {} to Floating IP neutron port {} mapping in Floating IP"
885                 + " Port Info Config DS failed", floatingIpId.getValue(), floatingIpPortId.getValue(), e);
886         }
887     }
888
889     private Set<FixedIps> getFixedIpSet(List<FixedIps> fixedIps) {
890         return fixedIps != null ? new HashSet<>(fixedIps) : Collections.emptySet();
891     }
892 }