2 * Copyright © 2015, 2018 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.netvirt.neutronvpn;
10 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
12 import com.google.common.base.Optional;
13 import com.google.common.base.Strings;
14 import com.google.gson.Gson;
15 import com.google.gson.JsonArray;
16 import com.google.gson.JsonElement;
17 import com.google.gson.JsonObject;
18 import java.time.Duration;
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;
27 import java.util.stream.Collectors;
28 import javax.annotation.PostConstruct;
29 import javax.inject.Singleton;
30 import org.apache.commons.lang3.ObjectUtils;
31 import org.eclipse.jdt.annotation.Nullable;
32 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
33 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
34 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
35 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
36 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
37 import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
38 import org.opendaylight.genius.infra.Datastore;
39 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
40 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
41 import org.opendaylight.genius.infra.TypedWriteTransaction;
42 import org.opendaylight.genius.mdsalutil.MDSALUtil;
43 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
44 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
45 import org.opendaylight.netvirt.elanmanager.api.IElanService;
46 import org.opendaylight.netvirt.neutronvpn.api.enums.IpVersionChoice;
47 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
48 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.L2vlan;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.SplitHorizon;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.SplitHorizonBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAcl;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAclBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceKey;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.elan._interface.StaticMacEntries;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.port.id.subport.data.PortIdToSubport;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.binding.rev150712.PortBindingExtension;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.hostconfig.rev150712.hostconfig.attributes.hostconfigs.Hostconfig;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
82 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
83 import org.slf4j.Logger;
84 import org.slf4j.LoggerFactory;
87 public class NeutronPortChangeListener extends AsyncDataTreeChangeListenerBase<Port, NeutronPortChangeListener> {
88 private static final Logger LOG = LoggerFactory.getLogger(NeutronPortChangeListener.class);
89 private final DataBroker dataBroker;
90 private final ManagedNewTransactionRunner txRunner;
91 private final NeutronvpnManager nvpnManager;
92 private final NeutronvpnNatManager nvpnNatManager;
93 private final NeutronSubnetGwMacResolver gwMacResolver;
94 private final IElanService elanService;
95 private final JobCoordinator jobCoordinator;
96 private final NeutronvpnUtils neutronvpnUtils;
97 private final HostConfigCache hostConfigCache;
98 private final DataTreeEventCallbackRegistrar eventCallbacks;
100 public NeutronPortChangeListener(final DataBroker dataBroker,
101 final NeutronvpnManager neutronvpnManager,
102 final NeutronvpnNatManager neutronvpnNatManager,
103 final NeutronSubnetGwMacResolver gwMacResolver,
104 final IElanService elanService,
105 final JobCoordinator jobCoordinator,
106 final NeutronvpnUtils neutronvpnUtils,
107 final HostConfigCache hostConfigCache,
108 final DataTreeEventCallbackRegistrar dataTreeEventCallbackRegistrar) {
109 super(Port.class, NeutronPortChangeListener.class);
110 this.dataBroker = dataBroker;
111 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
112 nvpnManager = neutronvpnManager;
113 nvpnNatManager = neutronvpnNatManager;
114 this.gwMacResolver = gwMacResolver;
115 this.elanService = elanService;
116 this.jobCoordinator = jobCoordinator;
117 this.neutronvpnUtils = neutronvpnUtils;
118 this.hostConfigCache = hostConfigCache;
119 this.eventCallbacks = dataTreeEventCallbackRegistrar;
125 LOG.info("{} init", getClass().getSimpleName());
126 registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
130 protected InstanceIdentifier<Port> getWildCardPath() {
131 return InstanceIdentifier.create(Neutron.class).child(Ports.class).child(Port.class);
135 protected NeutronPortChangeListener getDataTreeChangeListener() {
136 return NeutronPortChangeListener.this;
141 protected void add(InstanceIdentifier<Port> identifier, Port input) {
142 LOG.trace("Received port add event: port={}", input);
143 String portName = input.getUuid().getValue();
144 LOG.trace("Adding Port : key: {}, value={}", identifier, input);
145 Network network = neutronvpnUtils.getNeutronNetwork(input.getNetworkId());
146 if (network == null || !NeutronvpnUtils.isNetworkTypeSupported(network)) {
147 LOG.warn("neutron vpn received a port add() for a network without a provider extension augmentation "
148 + "or with an unsupported network type for the port {} which is part of network {}",
153 neutronvpnUtils.addToPortCache(input);
154 String portStatus = NeutronUtils.PORT_STATUS_DOWN;
155 if (!Strings.isNullOrEmpty(input.getDeviceOwner()) && !Strings.isNullOrEmpty(input.getDeviceId())) {
156 if (NeutronConstants.DEVICE_OWNER_ROUTER_INF.equals(input.getDeviceOwner())) {
157 handleRouterInterfaceAdded(input);
158 NeutronUtils.createPortStatus(input.getUuid().getValue(), NeutronUtils.PORT_STATUS_ACTIVE, dataBroker);
161 if (NeutronConstants.DEVICE_OWNER_GATEWAY_INF.equals(input.getDeviceOwner())) {
162 handleRouterGatewayUpdated(input, false);
163 portStatus = NeutronUtils.PORT_STATUS_ACTIVE;
164 } else if (NeutronConstants.DEVICE_OWNER_FLOATING_IP.equals(input.getDeviceOwner())) {
165 handleFloatingIpPortUpdated(null, input);
166 portStatus = NeutronUtils.PORT_STATUS_ACTIVE;
169 // Switchdev ports need to be bounded to a host before creation
170 // in order to validate the supported vnic types from the hostconfig
171 if (input.getFixedIps() != null
172 && !input.getFixedIps().isEmpty()
173 && !(isPortTypeSwitchdev(input) && !isPortBound(input))) {
174 handleNeutronPortCreated(input);
176 NeutronUtils.createPortStatus(input.getUuid().getValue(), portStatus, dataBroker);
180 protected void remove(InstanceIdentifier<Port> identifier, Port input) {
181 LOG.trace("Removing Port : key: {}, value={}", identifier, input);
182 Network network = neutronvpnUtils.getNeutronNetwork(input.getNetworkId());
183 // need to proceed with deletion in case network is null for a case where v2 sync happens and a read for
184 // network from NN returns null, but the deletion process for port needs to continue
185 if (network != null && !NeutronvpnUtils.isNetworkTypeSupported(network)) {
186 String portName = input.getUuid().getValue();
187 LOG.warn("neutron vpn received a port remove() for a network without a provider extension augmentation "
188 + "or with an unsupported network type for the port {} which is part of network {}",
192 neutronvpnUtils.removeFromPortCache(input);
193 NeutronUtils.deletePortStatus(input.getUuid().getValue(), dataBroker);
195 if (!Strings.isNullOrEmpty(input.getDeviceOwner()) && !Strings.isNullOrEmpty(input.getDeviceId())) {
196 if (NeutronConstants.DEVICE_OWNER_ROUTER_INF.equals(input.getDeviceOwner())) {
197 handleRouterInterfaceRemoved(input);
198 /* nothing else to do here */
200 } else if (NeutronConstants.DEVICE_OWNER_GATEWAY_INF.equals(input.getDeviceOwner())
201 || NeutronConstants.DEVICE_OWNER_FLOATING_IP.equals(input.getDeviceOwner())) {
202 handleRouterGatewayUpdated(input, true);
203 elanService.removeKnownL3DmacAddress(input.getMacAddress().getValue(), input.getNetworkId().getValue());
206 if (input.getFixedIps() != null) {
207 handleNeutronPortDeleted(input);
212 protected void update(InstanceIdentifier<Port> identifier, Port original, Port update) {
213 LOG.trace("Received port update event: original={}, update={}", original, update);
214 // Switchdev ports need to be bounded to a host before creation
215 // in order to validate the supported vnic types from the hostconfig
216 if (isPortTypeSwitchdev(original)
217 && !isPortBound(original)
218 && isPortBound(update)) {
219 handleNeutronPortCreated(update);
221 final String portName = update.getUuid().getValue();
222 Network network = neutronvpnUtils.getNeutronNetwork(update.getNetworkId());
223 LOG.info("Update port {} from network {}", portName, update.getNetworkId().toString());
224 if (network == null || !NeutronvpnUtils.isNetworkTypeSupported(network)) {
225 LOG.warn("neutron vpn received a port update() for a network without a provider extension augmentation "
226 + "or with an unsupported network type for the port {} which is part of network {}",
230 neutronvpnUtils.addToPortCache(update);
232 if ((Strings.isNullOrEmpty(original.getDeviceOwner()) || Strings.isNullOrEmpty(original.getDeviceId())
233 || NeutronConstants.FLOATING_IP_DEVICE_ID_PENDING.equalsIgnoreCase(original.getDeviceId()))
234 && !Strings.isNullOrEmpty(update.getDeviceOwner()) && !Strings.isNullOrEmpty(update.getDeviceId())) {
235 if (NeutronConstants.DEVICE_OWNER_ROUTER_INF.equals(update.getDeviceOwner())) {
236 handleRouterInterfaceAdded(update);
239 if (NeutronConstants.DEVICE_OWNER_GATEWAY_INF.equals(update.getDeviceOwner())) {
240 handleRouterGatewayUpdated(update, false);
241 } else if (NeutronConstants.DEVICE_OWNER_FLOATING_IP.equals(update.getDeviceOwner())) {
242 handleFloatingIpPortUpdated(original, update);
245 Set<FixedIps> oldIPs = getFixedIpSet(original.getFixedIps());
246 Set<FixedIps> newIPs = getFixedIpSet(update.getFixedIps());
247 if (!oldIPs.equals(newIPs)) {
248 handleNeutronPortUpdated(original, update);
252 // check if port security enabled/disabled as part of port update
253 boolean origSecurityEnabled = NeutronvpnUtils.getPortSecurityEnabled(original);
254 boolean updatedSecurityEnabled = NeutronvpnUtils.getPortSecurityEnabled(update);
256 if (origSecurityEnabled || updatedSecurityEnabled) {
257 InstanceIdentifier<Interface> interfaceIdentifier = NeutronvpnUtils.buildVlanInterfaceIdentifier(portName);
258 jobCoordinator.enqueueJob("PORT- " + portName,
259 () -> Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
261 Optional<Interface> optionalInf =
262 confTx.read(interfaceIdentifier).get();
263 if (optionalInf.isPresent()) {
264 InterfaceBuilder interfaceBuilder = new InterfaceBuilder(optionalInf.get());
265 InterfaceAcl infAcl = handlePortSecurityUpdated(original, update,
266 origSecurityEnabled, updatedSecurityEnabled, interfaceBuilder).build();
267 interfaceBuilder.addAugmentation(InterfaceAcl.class, infAcl);
268 LOG.info("update: Of-port-interface updation for port {}", portName);
269 // Update OFPort interface for this neutron port
270 confTx.put(interfaceIdentifier, interfaceBuilder.build());
272 LOG.warn("update: Interface {} is not present", portName);
278 private void handleFloatingIpPortUpdated(@Nullable Port original, Port update) {
279 if ((original == null || NeutronConstants.FLOATING_IP_DEVICE_ID_PENDING.equals(original.getDeviceId()))
280 && !NeutronConstants.FLOATING_IP_DEVICE_ID_PENDING.equals(update.getDeviceId())) {
281 // populate floating-ip uuid and floating-ip port attributes (uuid, mac and subnet id for the ONLY
282 // fixed IP) to be used by NAT, depopulated in NATService once mac is retrieved in the removal path
283 addToFloatingIpPortInfo(new Uuid(update.getDeviceId()), update.getUuid(), update.getFixedIps().get(0)
284 .getSubnetId(), update.getMacAddress().getValue());
285 elanService.addKnownL3DmacAddress(update.getMacAddress().getValue(), update.getNetworkId().getValue());
289 private void handleRouterInterfaceAdded(Port routerPort) {
290 if (routerPort.getDeviceId() != null) {
291 Uuid routerId = new Uuid(routerPort.getDeviceId());
292 Uuid infNetworkId = routerPort.getNetworkId();
293 Uuid existingVpnId = neutronvpnUtils.getVpnForNetwork(infNetworkId);
295 elanService.addKnownL3DmacAddress(routerPort.getMacAddress().getValue(), infNetworkId.getValue());
296 if (existingVpnId == null) {
297 Set<Uuid> listVpnIds = new HashSet<>();
298 Uuid vpnId = neutronvpnUtils.getVpnForRouter(routerId, true);
302 listVpnIds.add(vpnId);
303 Uuid internetVpnId = neutronvpnUtils.getInternetvpnUuidBoundToRouterId(routerId);
304 List<Subnetmap> subnetMapList = new ArrayList<>();
305 boolean portIsIpv6 = false;
306 for (FixedIps portIP : routerPort.nonnullFixedIps()) {
307 // NOTE: Please donot change the order of calls to updateSubnetNodeWithFixedIP
308 // and addSubnetToVpn here
309 if (internetVpnId != null
310 && portIP.getIpAddress().getIpv6Address() != null) {
313 String ipValue = portIP.getIpAddress().stringValue();
314 Uuid subnetId = portIP.getSubnetId();
315 nvpnManager.updateSubnetNodeWithFixedIp(subnetId, routerId,
316 routerPort.getUuid(), ipValue, routerPort.getMacAddress().getValue(), vpnId);
317 Subnetmap sn = neutronvpnUtils.getSubnetmap(subnetId);
318 subnetMapList.add(sn);
321 listVpnIds.add(internetVpnId);
322 if (neutronvpnUtils.shouldVpnHandleIpVersionChoiceChange(
323 IpVersionChoice.IPV6, routerId, true)) {
324 neutronvpnUtils.updateVpnInstanceWithIpFamily(internetVpnId.getValue(), IpVersionChoice.IPV6,
326 neutronvpnUtils.updateVpnInstanceWithFallback(routerId, internetVpnId, true);
329 if (! subnetMapList.isEmpty()) {
330 nvpnManager.createVpnInterface(listVpnIds, routerPort, null);
332 IpVersionChoice ipVersion = IpVersionChoice.UNDEFINED;
333 for (FixedIps portIP : routerPort.nonnullFixedIps()) {
334 String ipValue = portIP.getIpAddress().stringValue();
335 ipVersion = NeutronvpnUtils.getIpVersionFromString(ipValue);
336 if (ipVersion.isIpVersionChosen(IpVersionChoice.IPV4)) {
337 nvpnManager.addSubnetToVpn(vpnId, portIP.getSubnetId(),
338 null /* internet-vpn-id */);
340 nvpnManager.addSubnetToVpn(vpnId, portIP.getSubnetId(), internetVpnId);
342 LOG.trace("NeutronPortChangeListener Add Subnet Gateway IP {} MAC {} Interface {} VPN {}",
343 ipValue, routerPort.getMacAddress(),
344 routerPort.getUuid().getValue(), vpnId.getValue());
346 if (neutronvpnUtils.shouldVpnHandleIpVersionChoiceChange(ipVersion, routerId, true)) {
347 LOG.debug("vpnInstanceOpDataEntry is getting update with ip address family {} for VPN {}",
348 ipVersion, vpnId.getValue());
349 neutronvpnUtils.updateVpnInstanceWithIpFamily(vpnId.getValue(), ipVersion, true);
351 nvpnManager.addToNeutronRouterInterfacesMap(routerId, routerPort.getUuid().getValue());
352 jobCoordinator.enqueueJob(routerId.toString(), () -> {
353 nvpnNatManager.handleSubnetsForExternalRouter(routerId);
354 return Collections.emptyList();
356 ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
358 String portInterfaceName = createOfPortInterface(routerPort, confTx);
359 createElanInterface(routerPort, portInterfaceName, confTx);
360 }), LOG, "Error creating ELAN interface for {}", routerPort);
362 LOG.error("Neutron network {} corresponding to router interface port {} for neutron router {}"
363 + " already associated to VPN {}", infNetworkId.getValue(), routerPort.getUuid().getValue(),
364 routerId.getValue(), existingVpnId.getValue());
369 private void handleRouterInterfaceRemoved(Port routerPort) {
370 if (routerPort.getDeviceId() != null) {
371 Uuid routerId = new Uuid(routerPort.getDeviceId());
372 Uuid infNetworkId = routerPort.getNetworkId();
373 elanService.removeKnownL3DmacAddress(routerPort.getMacAddress().getValue(), infNetworkId.getValue());
374 Uuid vpnId = ObjectUtils.defaultIfNull(neutronvpnUtils.getVpnForRouter(routerId, true),
376 List<FixedIps> portIps = routerPort.nonnullFixedIps();
377 boolean vpnInstanceInternetIpVersionRemoved = false;
378 Uuid vpnInstanceInternetUuid = null;
379 for (FixedIps portIP : portIps) {
380 // Internet VPN : flush InternetVPN first
381 Uuid subnetId = portIP.getSubnetId();
382 Subnetmap sn = neutronvpnUtils.getSubnetmap(subnetId);
383 if (sn != null && sn.getInternetVpnId() != null) {
384 if (neutronvpnUtils.shouldVpnHandleIpVersionChangeToRemove(sn, sn.getInternetVpnId())) {
385 vpnInstanceInternetIpVersionRemoved = true;
386 vpnInstanceInternetUuid = sn.getInternetVpnId();
388 nvpnManager.updateVpnInternetForSubnet(sn, sn.getInternetVpnId(), false);
391 /* Remove ping responder for router interfaces
392 * A router interface reference in a VPN will have to be removed before the host interface references
393 * for that subnet in the VPN are removed. This is to ensure that the FIB Entry of the router interface
394 * is not the last entry to be removed for that subnet in the VPN.
395 * If router interface FIB entry is the last to be removed for a subnet in a VPN , then all the host
396 * interface references in the vpn will already have been cleared, which will cause failures in
397 * cleanup of router interface flows*/
398 nvpnManager.deleteVpnInterface(routerPort.getUuid().getValue(),
399 null /* vpn-id */, null /* wrtConfigTxn*/);
400 final Uuid internetVpnId = vpnInstanceInternetUuid;
401 // update RouterInterfaces map
402 ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
404 IpVersionChoice ipVersion = IpVersionChoice.UNDEFINED;
405 for (FixedIps portIP : portIps) {
406 Subnetmap sn = neutronvpnUtils.getSubnetmap(portIP.getSubnetId());
407 // router Port have either IPv4 or IPv6, never both
408 ipVersion = neutronvpnUtils.getIpVersionFromString(sn.getSubnetIp());
409 String ipValue = portIP.getIpAddress().stringValue();
410 neutronvpnUtils.removeVpnPortFixedIpToPort(vpnId.getValue(), ipValue, confTx);
411 // NOTE: Please donot change the order of calls to removeSubnetFromVpn and
412 // and updateSubnetNodeWithFixedIP
413 nvpnManager.removeSubnetFromVpn(vpnId, portIP.getSubnetId(), internetVpnId);
414 nvpnManager.updateSubnetNodeWithFixedIp(portIP.getSubnetId(), null, null,
417 nvpnManager.removeFromNeutronRouterInterfacesMap(routerId, routerPort.getUuid().getValue());
418 deleteElanInterface(routerPort.getUuid().getValue(), confTx);
419 deleteOfPortInterface(routerPort, confTx);
420 jobCoordinator.enqueueJob(routerId.toString(), () -> {
421 nvpnNatManager.handleSubnetsForExternalRouter(routerId);
422 return Collections.emptyList();
424 if (neutronvpnUtils.shouldVpnHandleIpVersionChoiceChange(ipVersion, routerId, false)) {
425 LOG.debug("vpnInstanceOpDataEntry is getting update with ip address family {} for VPN {}",
426 ipVersion, vpnId.getValue());
427 neutronvpnUtils.updateVpnInstanceWithIpFamily(vpnId.getValue(), ipVersion, false);
429 }), LOG, "Error handling interface removal");
430 if (vpnInstanceInternetIpVersionRemoved) {
431 neutronvpnUtils.updateVpnInstanceWithIpFamily(vpnInstanceInternetUuid.getValue(),
432 IpVersionChoice.IPV6, false);
433 neutronvpnUtils.updateVpnInstanceWithFallback(routerId, vpnInstanceInternetUuid, false);
438 private void handleRouterGatewayUpdated(Port routerGwPort, boolean isRtrGwRemoved) {
439 Uuid routerId = new Uuid(routerGwPort.getDeviceId());
440 Uuid networkId = routerGwPort.getNetworkId();
441 Network network = neutronvpnUtils.getNeutronNetwork(networkId);
442 if (network == null) {
445 boolean isExternal = NeutronvpnUtils.getIsExternal(network);
447 Uuid vpnInternetId = neutronvpnUtils.getVpnForNetwork(networkId);
448 if (vpnInternetId != null) {
449 if (!isRtrGwRemoved) {
450 nvpnManager.updateVpnMaps(vpnInternetId, null, routerId, null, null);
452 List<Subnetmap> snList = neutronvpnUtils.getNeutronRouterSubnetMaps(routerId);
453 for (Subnetmap sn : snList) {
454 if (sn.getNetworkId() == networkId) {
457 if (NeutronvpnUtils.getIpVersionFromString(sn.getSubnetIp()) != IpVersionChoice.IPV6) {
460 if (isRtrGwRemoved) {
461 nvpnManager.removeV6PrivateSubnetToExtNetwork(routerId, vpnInternetId, sn);
463 nvpnManager.addV6PrivateSubnetToExtNetwork(routerId, vpnInternetId, sn);
466 //Update Internet BGP-VPN
467 if (isRtrGwRemoved) {
468 nvpnManager.updateVpnMaps(vpnInternetId, null, null, null, null);
472 elanService.addKnownL3DmacAddress(routerGwPort.getMacAddress().getValue(), networkId.getValue());
474 Router router = neutronvpnUtils.getNeutronRouter(routerId);
475 if (router == null) {
476 LOG.warn("No router found for router GW port {} for router {}", routerGwPort.getUuid().getValue(),
477 routerId.getValue());
479 eventCallbacks.onAddOrUpdate(LogicalDatastoreType.CONFIGURATION,
480 neutronvpnUtils.getNeutronRouterIid(routerId), (unused, newRouter) -> {
481 setupGwMac(newRouter, routerGwPort, routerId);
482 return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
483 }, Duration.ofSeconds(3), iid -> {
484 LOG.error("GwPort {} added without Router", routerGwPort.getUuid().getValue());
488 setupGwMac(router, routerGwPort, routerId);
491 private void setupGwMac(Router router, Port routerGwPort, Uuid routerId) {
492 gwMacResolver.sendArpRequestsToExtGateways(router);
493 jobCoordinator.enqueueJob(routerId.toString(), () -> {
494 setExternalGwMac(routerGwPort, routerId);
495 return Collections.emptyList();
499 private void setExternalGwMac(Port routerGwPort, Uuid routerId) {
500 // During full-sync networking-odl syncs routers before ports. As such,
501 // the MAC of the router's gw port is not available to be set when the
502 // router is written. We catch that here.
503 InstanceIdentifier<Routers> routersId = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
504 Optional<Routers> optionalRouter = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, routersId);
505 if (!optionalRouter.isPresent()) {
509 Routers extRouters = optionalRouter.get();
510 if (extRouters.getExtGwMacAddress() != null) {
514 RoutersBuilder builder = new RoutersBuilder(extRouters);
515 builder.setExtGwMacAddress(routerGwPort.getMacAddress().getValue());
516 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, routersId, builder.build());
520 private String getPortHostId(final Port port) {
522 PortBindingExtension portBinding = port.augmentation(PortBindingExtension.class);
523 if (portBinding != null) {
524 return portBinding.getHostId();
531 private Hostconfig getHostConfig(final Port port) {
532 String hostId = getPortHostId(port);
533 if (hostId == null) {
536 Optional<Hostconfig> hostConfig;
538 hostConfig = this.hostConfigCache.get(hostId);
539 } catch (ReadFailedException e) {
540 LOG.error("failed to read host config from host {}", hostId, e);
543 return hostConfig.orNull();
546 private boolean isPortBound(final Port port) {
547 String hostId = getPortHostId(port);
548 return hostId != null && !hostId.isEmpty();
551 private boolean isPortVnicTypeDirect(Port port) {
552 PortBindingExtension portBinding = port.augmentation(PortBindingExtension.class);
553 if (portBinding == null || portBinding.getVnicType() == null) {
554 // By default, VNIC_TYPE is NORMAL
557 String vnicType = portBinding.getVnicType().trim().toLowerCase(Locale.getDefault());
558 return vnicType.equals(NeutronConstants.VNIC_TYPE_DIRECT);
561 private boolean isSupportedVnicTypeByHost(final Port port, final String vnicType) {
562 Hostconfig hostConfig = getHostConfig(port);
563 String supportStr = String.format("\"vnic_type\": \"%s\"", vnicType);
564 if (hostConfig != null && hostConfig.getConfig().contains(supportStr)) {
571 private Map<String, JsonElement> unmarshal(final String profile) {
572 if (null == profile) {
575 Gson gson = new Gson();
576 JsonObject jsonObject = gson.fromJson(profile, JsonObject.class);
577 Map<String, JsonElement> map = new HashMap<>();
578 for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
579 map.put(entry.getKey(), entry.getValue());
584 private boolean isPortTypeSwitchdev(final Port port) {
585 if (!isPortVnicTypeDirect(port)) {
589 PortBindingExtension portBinding = port.augmentation(PortBindingExtension.class);
590 String profile = portBinding.getProfile();
591 if (profile == null || profile.isEmpty()) {
592 LOG.debug("Port {} has no binding:profile values", port.getUuid());
596 Map<String, JsonElement> mapProfile = unmarshal(profile);
597 JsonElement capabilities = mapProfile.get(NeutronConstants.BINDING_PROFILE_CAPABILITIES);
598 LOG.debug("Port {} capabilities: {}", port.getUuid(), capabilities);
599 if (capabilities == null || !capabilities.isJsonArray()) {
600 LOG.debug("binding profile capabilities not in array format: {}", capabilities);
604 JsonArray capabilitiesArray = capabilities.getAsJsonArray();
605 Gson gson = new Gson();
606 JsonElement switchdevElement = gson.fromJson(NeutronConstants.SWITCHDEV, JsonElement.class);
607 return capabilitiesArray.contains(switchdevElement);
611 private void handleNeutronPortCreated(final Port port) {
612 final String portName = port.getUuid().getValue();
613 final Uuid portId = port.getUuid();
614 final List<FixedIps> portIpAddrsList = port.nonnullFixedIps();
615 if (NeutronConstants.IS_ODL_DHCP_PORT.test(port)) {
618 jobCoordinator.enqueueJob("PORT- " + portName, () -> {
619 // add direct port to subnetMaps config DS
620 if (!(NeutronUtils.isPortVnicTypeNormal(port)
621 || isPortTypeSwitchdev(port)
622 && isSupportedVnicTypeByHost(port, NeutronConstants.VNIC_TYPE_DIRECT))) {
623 for (FixedIps ip: portIpAddrsList) {
624 nvpnManager.updateSubnetmapNodeWithPorts(ip.getSubnetId(), null, portId);
626 LOG.info("Port {} is not a normal and not a direct with switchdev VNIC type ;"
627 + "OF Port interfaces are not created", portName);
628 return Collections.emptyList();
630 return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
631 LOG.info("Of-port-interface creation for port {}", portName);
632 // Create of-port interface for this neutron port
633 String portInterfaceName = createOfPortInterface(port, tx);
634 LOG.debug("Creating ELAN Interface for port {}", portName);
635 createElanInterface(port, portInterfaceName, tx);
636 Set<Uuid> vpnIdList = new HashSet<>();
637 Set<Uuid> routerIds = new HashSet<>();
638 for (FixedIps ip: portIpAddrsList) {
639 Subnetmap subnetMap = nvpnManager.updateSubnetmapNodeWithPorts(ip.getSubnetId(), portId, null);
640 if (subnetMap != null && subnetMap.getInternetVpnId() != null) {
641 if (!vpnIdList.contains(subnetMap.getInternetVpnId())) {
642 vpnIdList.add(subnetMap.getInternetVpnId());
645 if (subnetMap != null && subnetMap.getVpnId() != null) {
646 // can't use NeutronvpnUtils.getVpnForNetwork to optimise here, because it gives BGPVPN id
647 // obtained subnetMaps belongs to one network => vpnId must be the same for each port Ip
648 Uuid vpnId = subnetMap.getVpnId();
650 vpnIdList.add(vpnId);
653 if (subnetMap != null && subnetMap.getRouterId() != null) {
654 routerIds.add(subnetMap.getRouterId());
657 if (!vpnIdList.isEmpty()) {
658 // create new vpn-interface for neutron port
659 LOG.debug("handleNeutronPortCreated: Adding VPN Interface for port {} from network {}", portName,
660 port.getNetworkId().toString());
661 nvpnManager.createVpnInterface(vpnIdList, port, tx);
662 if (!routerIds.isEmpty()) {
663 for (Uuid routerId : routerIds) {
664 nvpnManager.addToNeutronRouterInterfacesMap(routerId,port.getUuid().getValue());
672 private void handleNeutronPortDeleted(final Port port) {
673 final String portName = port.getUuid().getValue();
674 final Uuid portId = port.getUuid();
675 final List<FixedIps> portIpsList = port.nonnullFixedIps();
676 jobCoordinator.enqueueJob("PORT- " + portName,
677 () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, confTx -> {
678 if (!(NeutronUtils.isPortVnicTypeNormal(port) || isPortTypeSwitchdev(port))) {
679 for (FixedIps ip : portIpsList) {
680 // remove direct port from subnetMaps config DS
681 nvpnManager.removePortsFromSubnetmapNode(ip.getSubnetId(), null, portId);
683 LOG.info("Port {} is not a normal and not a direct with switchdev VNIC type ;"
684 + "Skipping OF Port interfaces removal", portName);
688 Set<Uuid> routerIds = new HashSet<>();
689 Uuid internetVpnId = null;
690 for (FixedIps ip : portIpsList) {
691 Subnetmap subnetMap = nvpnManager.removePortsFromSubnetmapNode(ip.getSubnetId(), portId, null);
692 if (subnetMap == null) {
695 if (subnetMap.getVpnId() != null) {
696 // can't use NeutronvpnUtils.getVpnForNetwork to optimise here, because it gives BGPVPN id
697 // obtained subnetMaps belongs to one network => vpnId must be the same for each port Ip
698 vpnId = subnetMap.getVpnId();
700 if (subnetMap.getRouterId() != null) {
701 routerIds.add(subnetMap.getRouterId());
703 internetVpnId = subnetMap.getInternetVpnId();
705 if (NeutronConstants.DEVICE_OWNER_GATEWAY_INF.equals(port.getDeviceOwner())
706 || NeutronConstants.DEVICE_OWNER_FLOATING_IP.equals(port.getDeviceOwner())) {
707 String ipAddress = ip.getIpAddress().stringValue();
709 neutronvpnUtils.removeVpnPortFixedIpToPort(vpnId.getValue(), ipAddress, confTx);
711 if (internetVpnId != null) {
712 neutronvpnUtils.removeVpnPortFixedIpToPort(internetVpnId.getValue(),
717 if (vpnId != null || internetVpnId != null) {
718 // remove vpn-interface for this neutron port
719 LOG.debug("removing VPN Interface for port {}", portName);
720 if (!routerIds.isEmpty()) {
721 for (Uuid routerId : routerIds) {
722 nvpnManager.removeFromNeutronRouterInterfacesMap(routerId, portName);
725 nvpnManager.deleteVpnInterface(portName, null /* vpn-id */, confTx);
727 // Remove of-port interface for this neutron port
728 // ELAN interface is also implicitly deleted as part of this operation
729 LOG.debug("Of-port-interface removal for port {}", portName);
730 deleteOfPortInterface(port, confTx);
731 //dissociate fixedIP from floatingIP if associated
732 nvpnManager.dissociatefixedIPFromFloatingIP(port.getUuid().getValue());
737 private void handleNeutronPortUpdated(final Port portoriginal, final Port portupdate) {
738 final List<FixedIps> portoriginalIps = portoriginal.getFixedIps();
739 final List<FixedIps> portupdateIps = portupdate.getFixedIps();
740 if (portoriginalIps == null || portoriginalIps.isEmpty()) {
741 handleNeutronPortCreated(portupdate);
745 if (portupdateIps == null || portupdateIps.isEmpty()) {
746 LOG.info("Ignoring portUpdate (fixed_ip removal) for port {} as this case is handled "
747 + "during subnet deletion event.", portupdate.getUuid().getValue());
751 if (NeutronConstants.IS_ODL_DHCP_PORT.test(portupdate)) {
755 jobCoordinator.enqueueJob("PORT- " + portupdate.getUuid().getValue(),
756 () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, confTx -> {
757 final List<Uuid> originalSnMapsIds = portoriginalIps.stream().map(FixedIps::getSubnetId)
758 .collect(Collectors.toList());
759 final List<Uuid> updateSnMapsIds = portupdateIps.stream().map(FixedIps::getSubnetId)
760 .collect(Collectors.toList());
761 Set<Uuid> originalRouterIds = new HashSet<>();
762 Set<Uuid> oldVpnIds = new HashSet<>();
763 for (Uuid snId: originalSnMapsIds) {
764 if (!updateSnMapsIds.remove(snId)) {
765 // snId was present in originalSnMapsIds, but not in updateSnMapsIds
766 Subnetmap subnetMapOld = nvpnManager.removePortsFromSubnetmapNode(snId, portoriginal.getUuid(),
768 if (subnetMapOld != null && subnetMapOld.getVpnId() != null) {
769 oldVpnIds.add(subnetMapOld.getVpnId());
771 if (subnetMapOld != null && subnetMapOld.getInternetVpnId() != null) {
772 oldVpnIds.add(subnetMapOld.getInternetVpnId());
774 if (subnetMapOld != null && subnetMapOld.getRouterId() != null) {
775 originalRouterIds.add(subnetMapOld.getRouterId());
779 Set<Uuid> newVpnIds = new HashSet<>();
780 Set<Uuid> newRouterIds = new HashSet<>();
781 for (Uuid snId: updateSnMapsIds) {
782 Subnetmap subnetMapNew = nvpnManager.updateSubnetmapNodeWithPorts(snId, portupdate.getUuid(), null);
783 if (subnetMapNew != null) {
784 if (subnetMapNew.getVpnId() != null) {
785 newVpnIds.add(subnetMapNew.getVpnId());
787 if (subnetMapNew.getInternetVpnId() != null) {
788 newVpnIds.add(subnetMapNew.getInternetVpnId());
790 if (subnetMapNew.getRouterId() != null) {
791 newRouterIds.add(subnetMapNew.getRouterId());
795 if (!oldVpnIds.isEmpty()) {
796 LOG.info("removing VPN Interface for port {}", portoriginal.getUuid().getValue());
797 if (!originalRouterIds.isEmpty()) {
798 for (Uuid routerId : originalRouterIds) {
799 nvpnManager.removeFromNeutronRouterInterfacesMap(routerId,
800 portoriginal.getUuid().getValue());
803 nvpnManager.deleteVpnInterface(portoriginal.getUuid().getValue(),
804 null /* vpn-id */, confTx);
806 if (!newVpnIds.isEmpty()) {
807 LOG.info("Adding VPN Interface for port {}", portupdate.getUuid().getValue());
808 nvpnManager.createVpnInterface(newVpnIds, portupdate, confTx);
809 if (!newRouterIds.isEmpty()) {
810 for (Uuid routerId : newRouterIds) {
811 nvpnManager.addToNeutronRouterInterfacesMap(routerId,portupdate.getUuid().getValue());
819 private InterfaceAclBuilder handlePortSecurityUpdated(Port portOriginal,
820 Port portUpdated, boolean origSecurityEnabled, boolean updatedSecurityEnabled,
821 InterfaceBuilder interfaceBuilder) {
822 InterfaceAclBuilder interfaceAclBuilder = null;
823 if (origSecurityEnabled != updatedSecurityEnabled) {
824 interfaceAclBuilder = new InterfaceAclBuilder();
825 interfaceAclBuilder.setPortSecurityEnabled(updatedSecurityEnabled);
826 if (updatedSecurityEnabled) {
827 // Handle security group enabled
828 neutronvpnUtils.populateInterfaceAclBuilder(interfaceAclBuilder, portUpdated);
830 // Handle security group disabled
831 interfaceAclBuilder.setSecurityGroups(new ArrayList<>());
832 interfaceAclBuilder.setAllowedAddressPairs(new ArrayList<>());
833 interfaceAclBuilder.setSubnetInfo(new ArrayList<>());
836 if (updatedSecurityEnabled) {
837 // handle SG add/delete delta
838 InterfaceAcl interfaceAcl = interfaceBuilder.augmentation(InterfaceAcl.class);
839 interfaceAclBuilder = new InterfaceAclBuilder(interfaceAcl);
840 interfaceAclBuilder.setSecurityGroups(
841 NeutronvpnUtils.getUpdatedSecurityGroups(interfaceAcl.getSecurityGroups(),
842 portOriginal.getSecurityGroups(), portUpdated.getSecurityGroups()));
843 List<AllowedAddressPairs> updatedAddressPairs = NeutronvpnUtils.getUpdatedAllowedAddressPairs(
844 interfaceAcl.getAllowedAddressPairs(), portOriginal.getAllowedAddressPairs(),
845 portUpdated.getAllowedAddressPairs());
846 interfaceAclBuilder.setAllowedAddressPairs(NeutronvpnUtils.getAllowedAddressPairsForFixedIps(
847 updatedAddressPairs, portOriginal.getMacAddress(), portOriginal.getFixedIps(),
848 portUpdated.getFixedIps()));
850 if (portOriginal.getFixedIps() != null
851 && !portOriginal.getFixedIps().equals(portUpdated.getFixedIps())) {
852 neutronvpnUtils.populateSubnetInfo(interfaceAclBuilder, portUpdated);
856 return interfaceAclBuilder;
859 private String createOfPortInterface(Port port, TypedWriteTransaction<Datastore.Configuration> wrtConfigTxn) {
860 Interface inf = createInterface(port);
861 String infName = inf.getName();
863 InstanceIdentifier<Interface> interfaceIdentifier = NeutronvpnUtils.buildVlanInterfaceIdentifier(infName);
865 Optional<Interface> optionalInf =
866 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
867 interfaceIdentifier);
868 if (!optionalInf.isPresent()) {
869 wrtConfigTxn.put(interfaceIdentifier, inf);
871 LOG.warn("Interface {} is already present", infName);
873 } catch (ReadFailedException e) {
874 LOG.error("failed to create interface {}", infName, e);
879 private Interface createInterface(Port port) {
880 String interfaceName = port.getUuid().getValue();
881 IfL2vlan.L2vlanMode l2VlanMode = IfL2vlan.L2vlanMode.Trunk;
882 InterfaceBuilder interfaceBuilder = new InterfaceBuilder();
883 IfL2vlanBuilder ifL2vlanBuilder = new IfL2vlanBuilder();
885 Network network = neutronvpnUtils.getNeutronNetwork(port.getNetworkId());
886 Boolean isVlanTransparent = network.isVlanTransparent();
887 if (isVlanTransparent != null && isVlanTransparent) {
888 l2VlanMode = IfL2vlan.L2vlanMode.Transparent;
890 PortIdToSubport portIdToSubport = neutronvpnUtils.getPortIdToSubport(port.getUuid());
891 if (portIdToSubport != null) {
892 l2VlanMode = IfL2vlan.L2vlanMode.TrunkMember;
893 ifL2vlanBuilder.setVlanId(new VlanId(portIdToSubport.getVlanId().intValue()));
894 String parentRefName = portIdToSubport.getTrunkPortId().getValue();
895 ParentRefsBuilder parentRefsBuilder = new ParentRefsBuilder().setParentInterface(parentRefName);
896 interfaceBuilder.addAugmentation(ParentRefs.class, parentRefsBuilder.build());
897 SplitHorizon splitHorizon =
898 new SplitHorizonBuilder().setOverrideSplitHorizonProtection(true).build();
899 interfaceBuilder.addAugmentation(SplitHorizon.class, splitHorizon);
903 ifL2vlanBuilder.setL2vlanMode(l2VlanMode);
905 interfaceBuilder.setEnabled(true).setName(interfaceName).setType(L2vlan.class)
906 .addAugmentation(IfL2vlan.class, ifL2vlanBuilder.build());
908 if (NeutronvpnUtils.getPortSecurityEnabled(port)) {
909 InterfaceAclBuilder interfaceAclBuilder = new InterfaceAclBuilder();
910 interfaceAclBuilder.setPortSecurityEnabled(true);
911 neutronvpnUtils.populateInterfaceAclBuilder(interfaceAclBuilder, port);
912 interfaceBuilder.addAugmentation(InterfaceAcl.class, interfaceAclBuilder.build());
914 return interfaceBuilder.build();
917 private void deleteOfPortInterface(Port port, TypedWriteTransaction<Datastore.Configuration> wrtConfigTxn) {
918 String name = port.getUuid().getValue();
919 LOG.debug("Removing OFPort Interface {}", name);
920 InstanceIdentifier<Interface> interfaceIdentifier = NeutronvpnUtils.buildVlanInterfaceIdentifier(name);
922 Optional<Interface> optionalInf =
923 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
924 interfaceIdentifier);
925 if (optionalInf.isPresent()) {
926 wrtConfigTxn.delete(interfaceIdentifier);
928 LOG.warn("deleteOfPortInterface: Interface {} is not present", name);
930 } catch (ReadFailedException e) {
931 LOG.error("deleteOfPortInterface: Failed to delete interface {}", name, e);
935 private void createElanInterface(Port port, String name,
936 TypedWriteTransaction<Datastore.Configuration> wrtConfigTxn) {
937 String elanInstanceName = port.getNetworkId().getValue();
938 List<StaticMacEntries> staticMacEntries = NeutronvpnUtils.buildStaticMacEntry(port);
940 InstanceIdentifier<ElanInterface> id = InstanceIdentifier.builder(ElanInterfaces.class).child(ElanInterface
941 .class, new ElanInterfaceKey(name)).build();
942 ElanInterface elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName)
943 .setName(name).setStaticMacEntries(staticMacEntries).withKey(new ElanInterfaceKey(name)).build();
944 wrtConfigTxn.put(id, elanInterface);
945 LOG.debug("Creating new ELan Interface {}", elanInterface);
948 private void deleteElanInterface(String name, TypedWriteTransaction<Datastore.Configuration> wrtConfigTxn) {
949 InstanceIdentifier<ElanInterface> id = InstanceIdentifier.builder(ElanInterfaces.class).child(ElanInterface
950 .class, new ElanInterfaceKey(name)).build();
951 wrtConfigTxn.delete(id);
954 // TODO Clean up the exception handling
955 @SuppressWarnings("checkstyle:IllegalCatch")
956 private void addToFloatingIpPortInfo(Uuid floatingIpId, Uuid floatingIpPortId, Uuid floatingIpPortSubnetId, String
957 floatingIpPortMacAddress) {
958 InstanceIdentifier id = NeutronvpnUtils.buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
960 FloatingIpIdToPortMappingBuilder floatingipIdToPortMacMappingBuilder = new
961 FloatingIpIdToPortMappingBuilder().withKey(new FloatingIpIdToPortMappingKey(floatingIpId))
962 .setFloatingIpId(floatingIpId).setFloatingIpPortId(floatingIpPortId)
963 .setFloatingIpPortSubnetId(floatingIpPortSubnetId)
964 .setFloatingIpPortMacAddress(floatingIpPortMacAddress);
965 LOG.debug("Creating floating IP UUID {} to Floating IP neutron port {} mapping in Floating IP"
966 + " Port Info Config DS", floatingIpId.getValue(), floatingIpPortId.getValue());
967 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id,
968 floatingipIdToPortMacMappingBuilder.build());
969 } catch (Exception e) {
970 LOG.error("Creating floating IP UUID {} to Floating IP neutron port {} mapping in Floating IP"
971 + " Port Info Config DS failed", floatingIpId.getValue(), floatingIpPortId.getValue(), e);
975 private Set<FixedIps> getFixedIpSet(List<FixedIps> fixedIps) {
976 return fixedIps != null ? new HashSet<>(fixedIps) : Collections.emptySet();