-/*\r
- * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.netvirt.natservice.internal;\r
-\r
-import com.google.common.base.Optional;\r
-\r
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;\r
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
-import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;\r
-import org.opendaylight.genius.mdsalutil.MDSALUtil;\r
-import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;\r
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpMap;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.IpMapping;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMappingKey;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;\r
-import org.opendaylight.yangtools.concepts.ListenerRegistration;\r
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;\r
-import org.opendaylight.yangtools.yang.common.RpcResult;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-import java.math.BigInteger;\r
-import java.util.List;\r
-import java.util.concurrent.ExecutionException;\r
-import java.util.concurrent.Future;\r
-\r
-import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fib.rpc.rev160121.FibRpcService;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.VpnRpcService;\r
-\r
-/**\r
- * Created by ESUMAMS on 1/21/2016.\r
- */\r
-public class ExternalNetworksChangeListener extends AsyncDataTreeChangeListenerBase<Networks, ExternalNetworksChangeListener>\r
-{\r
- private static final Logger LOG = LoggerFactory.getLogger( ExternalNetworksChangeListener.class);\r
-\r
- private ListenerRegistration<DataChangeListener> listenerRegistration;\r
- private final DataBroker dataBroker;\r
- private IMdsalApiManager mdsalManager;\r
- //private VpnFloatingIpHandler vpnFloatingIpHandler;\r
- private FloatingIPListener floatingIpListener;\r
- private ExternalRoutersListener externalRouterListener;\r
- private OdlInterfaceRpcService interfaceManager;\r
- private NaptManager naptManager;\r
-\r
- private IBgpManager bgpManager;\r
- private VpnRpcService vpnService;\r
- private FibRpcService fibService;\r
-\r
-\r
- private ExternalRoutersListener externalRoutersListener;\r
-\r
- void setMdsalManager(IMdsalApiManager mdsalManager) {\r
- this.mdsalManager = mdsalManager;\r
- }\r
-\r
- void setInterfaceManager(OdlInterfaceRpcService interfaceManager) {\r
- this.interfaceManager = interfaceManager;\r
- }\r
-\r
- void setFloatingIpListener(FloatingIPListener floatingIpListener) {\r
- this.floatingIpListener = floatingIpListener;\r
- }\r
-\r
- void setExternalRoutersListener(ExternalRoutersListener externalRoutersListener) {\r
- this.externalRouterListener = externalRoutersListener;\r
- }\r
-\r
- public void setBgpManager(IBgpManager bgpManager) {\r
- this.bgpManager = bgpManager;\r
- }\r
-\r
- public void setNaptManager(NaptManager naptManager) {\r
- this.naptManager = naptManager;\r
- }\r
-\r
- public void setVpnService(VpnRpcService vpnService) {\r
- this.vpnService = vpnService;\r
- }\r
-\r
- public void setFibService(FibRpcService fibService) {\r
- this.fibService = fibService;\r
- }\r
-\r
- public void setListenerRegistration(ListenerRegistration<DataChangeListener> listenerRegistration) {\r
- this.listenerRegistration = listenerRegistration;\r
- }\r
-\r
- public ExternalNetworksChangeListener(final DataBroker dataBroker ) {\r
- super( Networks.class, ExternalNetworksChangeListener.class );\r
- this.dataBroker = dataBroker;\r
- }\r
-\r
-\r
- protected InstanceIdentifier<Networks> getWildCardPath() {\r
- return InstanceIdentifier.create(ExternalNetworks.class).child(Networks.class);\r
- }\r
-\r
-\r
- @Override\r
- protected void add(InstanceIdentifier<Networks> identifier, Networks networks) {\r
-\r
- }\r
-\r
- @Override\r
- protected ExternalNetworksChangeListener getDataTreeChangeListener() {\r
- return ExternalNetworksChangeListener.this;\r
- }\r
-\r
- @Override\r
- protected void remove(InstanceIdentifier<Networks> identifier, Networks networks) {\r
- if( identifier == null || networks == null || networks.getRouterIds().isEmpty() ) {\r
- LOG.info( "ExternalNetworksChangeListener:remove:: returning without processing since networks/identifier is null" );\r
- return;\r
- }\r
-\r
- for( Uuid routerId: networks.getRouterIds() ) {\r
- String routerName = routerId.toString();\r
-\r
- InstanceIdentifier<RouterToNaptSwitch> routerToNaptSwitchInstanceIdentifier =\r
- getRouterToNaptSwitchInstanceIdentifier( routerName);\r
-\r
- MDSALUtil.syncDelete( dataBroker, LogicalDatastoreType.OPERATIONAL, routerToNaptSwitchInstanceIdentifier );\r
-\r
- LOG.debug( "ExternalNetworksChangeListener:delete:: successful deletion of data in napt-switches container" );\r
- }\r
- }\r
-\r
- private static InstanceIdentifier<RouterToNaptSwitch> getRouterToNaptSwitchInstanceIdentifier( String routerName ) {\r
-\r
- return InstanceIdentifier.builder( NaptSwitches.class )\r
- .child( RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerName)).build();\r
-\r
- }\r
-\r
- public void close() throws Exception {\r
- if (listenerRegistration != null) {\r
- try {\r
- listenerRegistration.close();\r
- }\r
- catch (final Exception e) {\r
- LOG.error("Error when cleaning up ExternalNetworksChangeListener.", e);\r
- }\r
-\r
- listenerRegistration = null;\r
- }\r
- LOG.debug("ExternalNetworksChangeListener Closed");\r
- }\r
-\r
-\r
- @Override\r
- protected void update(InstanceIdentifier<Networks> identifier, Networks original, Networks update) {\r
- //Check for VPN disassociation\r
- Uuid originalVpn = original.getVpnid();\r
- Uuid updatedVpn = update.getVpnid();\r
- if(originalVpn == null && updatedVpn != null) {\r
- //external network is dis-associated from L3VPN instance\r
- associateExternalNetworkWithVPN(update);\r
- } else if(originalVpn != null && updatedVpn == null) {\r
- //external network is associated with vpn\r
- disassociateExternalNetworkFromVPN(update, originalVpn.getValue());\r
- //Remove the SNAT entries\r
- removeSnatEntries(original, original.getId());\r
- }\r
- }\r
-\r
- private void removeSnatEntries(Networks original, Uuid networkUuid) {\r
- List<Uuid> routerUuids = original.getRouterIds();\r
- for (Uuid routerUuid : routerUuids) {\r
- Long routerId = NatUtil.getVpnId(dataBroker, routerUuid.getValue());\r
- if (routerId == NatConstants.INVALID_ID) {\r
- LOG.error("NAT Service : Invalid routerId returned for routerName {}", routerUuid.getValue());\r
- return;\r
- }\r
- List<String> externalIps = NatUtil.getExternalIpsForRouter(dataBroker,routerId);\r
- externalRouterListener.handleDisableSnatInternetVpn(routerUuid.getValue(), networkUuid, externalIps, false, original.getVpnid().getValue());\r
- }\r
- }\r
-\r
- private void associateExternalNetworkWithVPN(Networks network) {\r
- List<Uuid> routerIds = network.getRouterIds();\r
- for(Uuid routerId : routerIds) {\r
- //long router = NatUtil.getVpnId(dataBroker, routerId.getValue());\r
-\r
- InstanceIdentifier<RouterPorts> routerPortsId = NatUtil.getRouterPortsId(routerId.getValue());\r
- Optional<RouterPorts> optRouterPorts = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, routerPortsId);\r
- if(!optRouterPorts.isPresent()) {\r
- LOG.debug("Could not read Router Ports data object with id: {} to handle associate ext nw {}", routerId, network.getId());\r
- continue;\r
- }\r
- RouterPorts routerPorts = optRouterPorts.get();\r
- List<Ports> interfaces = routerPorts.getPorts();\r
- for(Ports port : interfaces) {\r
- String portName = port.getPortName();\r
- BigInteger dpnId = getDpnForInterface(interfaceManager, portName);\r
- if(dpnId.equals(BigInteger.ZERO)) {\r
- LOG.debug("DPN not found for {}, skip handling of ext nw {} association", portName, network.getId());\r
- continue;\r
- }\r
- List<IpMapping> ipMapping = port.getIpMapping();\r
- for(IpMapping ipMap : ipMapping) {\r
- String externalIp = ipMap.getExternalIp();\r
- //remove all VPN related entries\r
- floatingIpListener.createNATFlowEntries(dpnId, portName, routerId.getValue(), network.getId(), ipMap.getInternalIp(), externalIp);\r
- }\r
- }\r
- }\r
-\r
- // SNAT\r
- for(Uuid routerId : routerIds) {\r
- LOG.debug("NAT Service : associateExternalNetworkWithVPN() for routerId {}", routerId);\r
- Uuid networkId = network.getId();\r
- if(networkId == null) {\r
- LOG.error("NAT Service : networkId is null for the router ID {}", routerId);\r
- return;\r
- }\r
- final String vpnName = network.getVpnid().getValue();\r
- if(vpnName == null) {\r
- LOG.error("NAT Service : No VPN associated with ext nw {} for router {}", networkId, routerId);\r
- return;\r
- }\r
-\r
- BigInteger dpnId = new BigInteger("0");\r
- InstanceIdentifier<RouterToNaptSwitch> routerToNaptSwitch = NatUtil.buildNaptSwitchRouterIdentifier(routerId.getValue());\r
- Optional<RouterToNaptSwitch> rtrToNapt = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, routerToNaptSwitch );\r
- if(rtrToNapt.isPresent()) {\r
- dpnId = rtrToNapt.get().getPrimarySwitchId();\r
- }\r
- LOG.debug("NAT Service : got primarySwitch as dpnId{} ", dpnId);\r
- if (dpnId == null || dpnId.equals(BigInteger.ZERO)) {\r
- LOG.debug("NAT Service : primary napt Switch not found for router {} in associateExternalNetworkWithVPN", routerId);\r
- return;\r
- }\r
-\r
- Long routerIdentifier = NatUtil.getVpnId(dataBroker, routerId.getValue());\r
- InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping> idBuilder =\r
- InstanceIdentifier.builder(IntextIpMap.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMappingKey(routerIdentifier));\r
- InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping> id = idBuilder.build();\r
- Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping> ipMapping = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);\r
- if (ipMapping.isPresent()) {\r
- List<IpMap> ipMaps = ipMapping.get().getIpMap();\r
- for (IpMap ipMap : ipMaps) {\r
- String externalIp = ipMap.getExternalIp();\r
- LOG.debug("NAT Service : got externalIp as {}", externalIp);\r
- LOG.debug("NAT Service : About to call advToBgpAndInstallFibAndTsFlows for dpnId {}, vpnName {} and externalIp {}", dpnId, vpnName, externalIp);\r
- externalRouterListener.advToBgpAndInstallFibAndTsFlows(dpnId, NatConstants.INBOUND_NAPT_TABLE, vpnName, NatUtil.getVpnId(dataBroker, routerId.getValue()), externalIp, vpnService, fibService, bgpManager, dataBroker, LOG);\r
- }\r
- } else {\r
- LOG.warn("NAT Service : No ipMapping present fot the routerId {}", routerId);\r
- }\r
-\r
- long vpnId = NatUtil.getVpnId(dataBroker, vpnName);\r
- // Install 47 entry to point to 21\r
- if(vpnId != -1) {\r
- LOG.debug("NAT Service : Calling externalRouterListener installNaptPfibEntry for donId {} and vpnId {}", dpnId, vpnId);\r
- externalRouterListener.installNaptPfibEntry(dpnId, vpnId);\r
- }\r
-\r
- }\r
-\r
- }\r
-\r
- private void disassociateExternalNetworkFromVPN(Networks network, String vpnName) {\r
- List<Uuid> routerIds = network.getRouterIds();\r
-\r
- //long vpnId = NatUtil.getVpnId(dataBroker, vpnName);\r
- for(Uuid routerId : routerIds) {\r
- //long router = NatUtil.getVpnId(dataBroker, routerId.getValue());\r
-\r
- InstanceIdentifier<RouterPorts> routerPortsId = NatUtil.getRouterPortsId(routerId.getValue());\r
- Optional<RouterPorts> optRouterPorts = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, routerPortsId);\r
- if(!optRouterPorts.isPresent()) {\r
- LOG.debug("Could not read Router Ports data object with id: {} to handle disassociate ext nw {}", routerId, network.getId());\r
- continue;\r
- }\r
- RouterPorts routerPorts = optRouterPorts.get();\r
- List<Ports> interfaces = routerPorts.getPorts();\r
- for(Ports port : interfaces) {\r
- String portName = port.getPortName();\r
- BigInteger dpnId = getDpnForInterface(interfaceManager, portName);\r
- if(dpnId.equals(BigInteger.ZERO)) {\r
- LOG.debug("DPN not found for {}, skip handling of ext nw {} disassociation", portName, network.getId());\r
- continue;\r
- }\r
- List<IpMapping> ipMapping = port.getIpMapping();\r
- for(IpMapping ipMap : ipMapping) {\r
- String externalIp = ipMap.getExternalIp();\r
- floatingIpListener.removeNATFlowEntries(dpnId, portName, vpnName, routerId.getValue(), network.getId(), ipMap.getInternalIp(), externalIp);\r
- }\r
- }\r
- }\r
- }\r
-\r
- public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {\r
- BigInteger nodeId = BigInteger.ZERO;\r
- try {\r
- GetDpidFromInterfaceInput\r
- dpIdInput =\r
- new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();\r
- Future<RpcResult<GetDpidFromInterfaceOutput>>\r
- dpIdOutput =\r
- interfaceManagerRpcService.getDpidFromInterface(dpIdInput);\r
- RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();\r
- if (dpIdResult.isSuccessful()) {\r
- nodeId = dpIdResult.getResult().getDpid();\r
- } else {\r
- LOG.error("Could not retrieve DPN Id for interface {}", ifName);\r
- }\r
- } catch (InterruptedException | ExecutionException e) {\r
- LOG.error("Exception when getting dpn for interface {}", ifName, e);\r
- }\r
- return nodeId;\r
- }\r
-\r
-}\r
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netvirt.natservice.internal;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.genius.mdsalutil.MDSALUtil;
+import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fib.rpc.rev160121.FibRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.config.rev170206.NatserviceConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.config.rev170206.NatserviceConfig.NatMode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.VpnRpcService;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class ExternalNetworksChangeListener
+ extends AsyncDataTreeChangeListenerBase<Networks, ExternalNetworksChangeListener> {
+ private static final Logger LOG = LoggerFactory.getLogger(ExternalNetworksChangeListener.class);
+ private final DataBroker dataBroker;
+ private final IMdsalApiManager mdsalManager;
+ private final FloatingIPListener floatingIpListener;
+ private final ExternalRoutersListener externalRouterListener;
+ private final OdlInterfaceRpcService interfaceManager;
+ private final NaptManager naptManager;
+ private final IBgpManager bgpManager;
+ private final VpnRpcService vpnService;
+ private final FibRpcService fibService;
+ private NatMode natMode = NatMode.Controller;
+
+ @Inject
+ public ExternalNetworksChangeListener(final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
+ final FloatingIPListener floatingIpListener,
+ final ExternalRoutersListener externalRouterListener,
+ final OdlInterfaceRpcService interfaceManager,
+ final NaptManager naptManager,
+ final IBgpManager bgpManager,
+ final VpnRpcService vpnService,
+ final FibRpcService fibService,
+ final NatserviceConfig config) {
+ super(Networks.class, ExternalNetworksChangeListener.class);
+ this.dataBroker = dataBroker;
+ this.mdsalManager = mdsalManager;
+ this.floatingIpListener = floatingIpListener;
+ this.externalRouterListener = externalRouterListener;
+ this.interfaceManager = interfaceManager;
+ this.naptManager = naptManager;
+ this.bgpManager = bgpManager;
+ this.vpnService = vpnService;
+ this.fibService = fibService;
+ if (config != null) {
+ this.natMode = config.getNatMode();
+ }
+ }
+
+ @Override
+ @PostConstruct
+ public void init() {
+ LOG.info("{} init", getClass().getSimpleName());
+ registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
+ }
+
+ @Override
+ protected InstanceIdentifier<Networks> getWildCardPath() {
+ return InstanceIdentifier.create(ExternalNetworks.class).child(Networks.class);
+ }
+
+ @Override
+ protected void add(InstanceIdentifier<Networks> identifier, Networks networks) {
+
+ }
+
+ @Override
+ protected ExternalNetworksChangeListener getDataTreeChangeListener() {
+ return ExternalNetworksChangeListener.this;
+ }
+
+ @Override
+ protected void remove(InstanceIdentifier<Networks> identifier, Networks networks) {
+ if (identifier == null || networks == null || networks.getRouterIds().isEmpty()) {
+ LOG.error("remove : returning without processing since networks/identifier is null");
+ return;
+ }
+
+ for (Uuid routerId: networks.getRouterIds()) {
+ String routerName = routerId.toString();
+
+ InstanceIdentifier<RouterToNaptSwitch> routerToNaptSwitchInstanceIdentifier =
+ getRouterToNaptSwitchInstanceIdentifier(routerName);
+
+ MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, routerToNaptSwitchInstanceIdentifier);
+
+ LOG.debug("remove : successful deletion of data in napt-switches container");
+ }
+ }
+
+ private static InstanceIdentifier<RouterToNaptSwitch> getRouterToNaptSwitchInstanceIdentifier(String routerName) {
+ return InstanceIdentifier.builder(NaptSwitches.class)
+ .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerName)).build();
+ }
+
+ @Override
+ protected void update(InstanceIdentifier<Networks> identifier, Networks original, Networks update) {
+ //Check for VPN disassociation
+ Uuid originalVpn = original.getVpnid();
+ Uuid updatedVpn = update.getVpnid();
+ WriteTransaction writeFlowInvTx = dataBroker.newWriteOnlyTransaction();
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ if (originalVpn == null && updatedVpn != null) {
+ //external network is dis-associated from L3VPN instance
+ associateExternalNetworkWithVPN(update, writeFlowInvTx);
+ } else if (originalVpn != null && updatedVpn == null) {
+ //external network is associated with vpn
+ disassociateExternalNetworkFromVPN(update, originalVpn.getValue());
+ //Remove the SNAT entries
+ removeSnatEntries(original, original.getId(), writeFlowInvTx);
+ }
+ futures.add(NatUtil.waitForTransactionToComplete(writeFlowInvTx));
+ }
+
+ private void removeSnatEntries(Networks original, Uuid networkUuid, WriteTransaction writeFlowInvTx) {
+ List<Uuid> routerUuids = original.getRouterIds();
+ for (Uuid routerUuid : routerUuids) {
+ Long routerId = NatUtil.getVpnId(dataBroker, routerUuid.getValue());
+ if (routerId == NatConstants.INVALID_ID) {
+ LOG.error("removeSnatEntries : Invalid routerId returned for routerName {}", routerUuid.getValue());
+ return;
+ }
+ Collection<String> externalIps = NatUtil.getExternalIpsForRouter(dataBroker,routerId);
+ if (natMode == NatMode.Controller) {
+ externalRouterListener.handleDisableSnatInternetVpn(routerUuid.getValue(), networkUuid, externalIps,
+ false, original.getVpnid().getValue(), writeFlowInvTx);
+ }
+ }
+ }
+
+ private void associateExternalNetworkWithVPN(Networks network, WriteTransaction writeFlowInvTx) {
+ List<Uuid> routerIds = network.getRouterIds();
+ for (Uuid routerId : routerIds) {
+ //long router = NatUtil.getVpnId(dataBroker, routerId.getValue());
+
+ InstanceIdentifier<RouterPorts> routerPortsId = NatUtil.getRouterPortsId(routerId.getValue());
+ Optional<RouterPorts> optRouterPorts = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
+ routerPortsId);
+ if (!optRouterPorts.isPresent()) {
+ LOG.debug("associateExternalNetworkWithVPN : Could not read Router Ports data object with id: {} "
+ + "to handle associate ext nw {}", routerId, network.getId());
+ continue;
+ }
+ RouterPorts routerPorts = optRouterPorts.get();
+ List<Ports> interfaces = routerPorts.getPorts();
+ for (Ports port : interfaces) {
+ String portName = port.getPortName();
+ BigInteger dpnId = NatUtil.getDpnForInterface(interfaceManager, portName);
+ if (dpnId.equals(BigInteger.ZERO)) {
+ LOG.debug("associateExternalNetworkWithVPN : DPN not found for {}, "
+ + "skip handling of ext nw {} association", portName, network.getId());
+ continue;
+ }
+ List<InternalToExternalPortMap> intExtPortMapList = port.getInternalToExternalPortMap();
+ for (InternalToExternalPortMap ipMap : intExtPortMapList) {
+ //remove all VPN related entries
+ floatingIpListener.createNATFlowEntries(dpnId, portName, routerId.getValue(), network.getId(),
+ ipMap);
+ }
+ }
+ }
+
+ // SNAT
+ for (Uuid routerId : routerIds) {
+ LOG.debug("associateExternalNetworkWithVPN() : for routerId {}", routerId);
+ Uuid networkId = network.getId();
+ if (networkId == null) {
+ LOG.error("associateExternalNetworkWithVPN : networkId is null for the router ID {}", routerId);
+ return;
+ }
+ final String vpnName = network.getVpnid().getValue();
+ if (vpnName == null) {
+ LOG.error("associateExternalNetworkWithVPN : No VPN associated with ext nw {} for router {}",
+ networkId, routerId);
+ return;
+ }
+
+ BigInteger dpnId = new BigInteger("0");
+ InstanceIdentifier<RouterToNaptSwitch> routerToNaptSwitch =
+ NatUtil.buildNaptSwitchRouterIdentifier(routerId.getValue());
+ Optional<RouterToNaptSwitch> rtrToNapt =
+ MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, routerToNaptSwitch);
+ if (rtrToNapt.isPresent()) {
+ dpnId = rtrToNapt.get().getPrimarySwitchId();
+ }
+ LOG.debug("associateExternalNetworkWithVPN : got primarySwitch as dpnId{} ", dpnId);
+ if (dpnId == null || dpnId.equals(BigInteger.ZERO)) {
+ LOG.error("associateExternalNetworkWithVPN : primary napt Switch not found for router {}", routerId);
+ return;
+ }
+
+ Long routerIdentifier = NatUtil.getVpnId(dataBroker, routerId.getValue());
+ InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
+ .rev160111.intext.ip.map.IpMapping> idBuilder =
+ InstanceIdentifier.builder(IntextIpMap.class)
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
+ .intext.ip.map.IpMapping.class,
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
+ .intext.ip.map.IpMappingKey(routerIdentifier));
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
+ .intext.ip.map.IpMapping> id = idBuilder.build();
+ Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
+ .intext.ip.map.IpMapping> ipMapping = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
+ if (ipMapping.isPresent()) {
+ List<IpMap> ipMaps = ipMapping.get().getIpMap();
+ for (IpMap ipMap : ipMaps) {
+ String externalIp = ipMap.getExternalIp();
+ LOG.debug("associateExternalNetworkWithVPN : Calling advToBgpAndInstallFibAndTsFlows for dpnId {},"
+ + "vpnName {} and externalIp {}", dpnId, vpnName, externalIp);
+ if (natMode == NatMode.Controller) {
+ externalRouterListener.advToBgpAndInstallFibAndTsFlows(dpnId, NwConstants.INBOUND_NAPT_TABLE,
+ vpnName, NatUtil.getVpnId(dataBroker, routerId.getValue()), routerId.getValue(),
+ externalIp, null /* external-router */, vpnService, fibService, bgpManager, dataBroker,
+ LOG, writeFlowInvTx);
+ }
+ }
+ } else {
+ LOG.warn("associateExternalNetworkWithVPN : No ipMapping present fot the routerId {}", routerId);
+ }
+
+ long vpnId = NatUtil.getVpnId(dataBroker, vpnName);
+ // Install 47 entry to point to 21
+ if (natMode == NatMode.Controller) {
+ externalRouterListener.installNaptPfibEntriesForExternalSubnets(routerId.getValue(), dpnId,
+ writeFlowInvTx);
+ if (vpnId != -1) {
+ LOG.debug("associateExternalNetworkWithVPN : Calling externalRouterListener installNaptPfibEntry "
+ + "for dpnId {} and vpnId {}", dpnId, vpnId);
+ externalRouterListener.installNaptPfibEntry(dpnId, vpnId, writeFlowInvTx);
+ }
+ }
+ }
+
+ }
+
+ private void disassociateExternalNetworkFromVPN(Networks network, String vpnName) {
+ List<Uuid> routerIds = network.getRouterIds();
+
+ for (Uuid routerId : routerIds) {
+ InstanceIdentifier<RouterPorts> routerPortsId = NatUtil.getRouterPortsId(routerId.getValue());
+ Optional<RouterPorts> optRouterPorts = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
+ routerPortsId);
+ if (!optRouterPorts.isPresent()) {
+ LOG.debug("disassociateExternalNetworkFromVPN : Could not read Router Ports data object with id: {} "
+ + "to handle disassociate ext nw {}", routerId, network.getId());
+ continue;
+ }
+ RouterPorts routerPorts = optRouterPorts.get();
+ List<Ports> interfaces = routerPorts.getPorts();
+ for (Ports port : interfaces) {
+ String portName = port.getPortName();
+ BigInteger dpnId = NatUtil.getDpnForInterface(interfaceManager, portName);
+ if (dpnId.equals(BigInteger.ZERO)) {
+ LOG.debug("disassociateExternalNetworkFromVPN : DPN not found for {},"
+ + "skip handling of ext nw {} disassociation", portName, network.getId());
+ continue;
+ }
+ List<InternalToExternalPortMap> intExtPortMapList = port.getInternalToExternalPortMap();
+ for (InternalToExternalPortMap intExtPortMap : intExtPortMapList) {
+ floatingIpListener.removeNATFlowEntries(dpnId, portName, vpnName, routerId.getValue(),
+ intExtPortMap);
+ }
+ }
+ }
+ }
+}