2 * Copyright (c) 2016 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.vpnservice.natservice.internal;
10 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
11 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
12 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
13 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
14 import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
15 import org.opendaylight.vpnservice.mdsalutil.ActionType;
16 import org.opendaylight.vpnservice.mdsalutil.FlowEntity;
17 import org.opendaylight.vpnservice.mdsalutil.InstructionInfo;
18 import org.opendaylight.vpnservice.mdsalutil.InstructionType;
19 import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
20 import org.opendaylight.vpnservice.mdsalutil.MatchFieldType;
21 import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
22 import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil;
23 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.ext.routers.Routers;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.FloatingIpInfo;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.floating.ip.info.RouterPorts;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.floating.ip.info.router.ports.Ports;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.floating.ip.info.router.ports.PortsBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.floating.ip.info.router.ports.ports.IpMapping;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.floating.ip.info.router.ports.ports.IpMappingBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.floating.ip.info.router.ports.ports.IpMappingKey;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.external.networks.Networks;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.external.networks.NetworksKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.ExternalNetworks;
36 import org.opendaylight.yangtools.concepts.ListenerRegistration;
37 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetDpidFromInterfaceInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetDpidFromInterfaceInputBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetDpidFromInterfaceOutput;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
45 import org.opendaylight.yangtools.yang.common.RpcResult;
47 import java.util.concurrent.ExecutionException;
48 import java.util.concurrent.Future;
50 import com.google.common.base.Optional;
51 import com.google.common.base.Strings;
53 import java.math.BigInteger;
54 import java.net.InetAddress;
55 import java.net.UnknownHostException;
56 import java.util.ArrayList;
57 import java.util.List;
60 * Created by emhamla on 1/18/2016.
62 public class FloatingIPListener extends org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener<IpMapping> implements AutoCloseable{
63 private static final Logger LOG = LoggerFactory.getLogger(FloatingIPListener.class);
64 private ListenerRegistration<DataChangeListener> listenerRegistration;
65 private final DataBroker broker;
66 private OdlInterfaceRpcService interfaceManager;
67 private IMdsalApiManager mdsalManager;
68 private FloatingIPHandler handler;
71 public FloatingIPListener (final DataBroker db) {
72 super(IpMapping.class);
77 void setFloatingIpHandler(FloatingIPHandler handler) {
78 this.handler = handler;
82 public void close() throws Exception {
83 if (listenerRegistration != null) {
85 listenerRegistration.close();
86 } catch (final Exception e) {
87 LOG.error("Error when cleaning up DataChangeListener.", e);
89 listenerRegistration = null;
91 LOG.info("FloatingIP Listener Closed");
94 private void registerListener(final DataBroker db) {
96 listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
97 getWildCardPath(), FloatingIPListener.this, AsyncDataBroker.DataChangeScope.SUBTREE);
98 } catch (final Exception e) {
99 LOG.error("FloatingIP DataChange listener registration fail!", e);
100 throw new IllegalStateException("FloatingIP Listener registration Listener failed.", e);
104 private InstanceIdentifier<IpMapping> getWildCardPath() {
105 return InstanceIdentifier.create(FloatingIpInfo.class).child(RouterPorts.class).child(Ports.class).child(IpMapping.class);
108 public void setInterfaceManager(OdlInterfaceRpcService interfaceManager) {
109 this.interfaceManager = interfaceManager;
112 public void setMdsalManager(IMdsalApiManager mdsalManager) {
113 this.mdsalManager = mdsalManager;
117 protected void add(final InstanceIdentifier<IpMapping> identifier,
118 final IpMapping mapping) {
119 LOG.trace("FloatingIPListener add ip mapping method - key: " + identifier + ", value=" + mapping );
120 processFloatingIPAdd(identifier, mapping);
124 protected void remove(InstanceIdentifier<IpMapping> identifier, IpMapping mapping) {
125 LOG.trace("FloatingIPListener remove ip mapping method - key: " + identifier + ", value=" + mapping );
126 processFloatingIPDel(identifier, mapping);
130 protected void update(InstanceIdentifier<IpMapping> identifier, IpMapping original, IpMapping update) {
131 LOG.trace("FloatingIPListener update ip mapping method - key: " + identifier + ", original=" + original + ", update=" + update );
134 public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
135 BigInteger nodeId = BigInteger.ZERO;
137 GetDpidFromInterfaceInput
139 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
140 Future<RpcResult<GetDpidFromInterfaceOutput>>
142 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
143 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
144 if (dpIdResult.isSuccessful()) {
145 nodeId = dpIdResult.getResult().getDpid();
147 LOG.error("Could not retrieve DPN Id for interface {}", ifName);
149 } catch (InterruptedException | ExecutionException e) {
150 LOG.error("Exception when getting dpn for interface {}", ifName, e);
155 private FlowEntity buildPreDNATFlowEntity(BigInteger dpId, String internalIp, String externalIp, long routerId, long vpnId) {
157 LOG.info("Bulding DNAT Flow entity for ip {} ", externalIp);
159 List<MatchInfo> matches = new ArrayList<MatchInfo>();
160 matches.add(new MatchInfo(MatchFieldType.eth_type,
161 new long[] { 0x0800L }));
163 matches.add(new MatchInfo(MatchFieldType.ipv4_destination, new String[] {
164 externalIp, "32" }));
166 // matches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
167 // BigInteger.valueOf(vpnId), MetaDataUtil.METADATA_MASK_VRFID }));
169 List<ActionInfo> actionsInfos = new ArrayList<ActionInfo>();
170 actionsInfos.add(new ActionInfo(ActionType.set_destination_ip, new String[]{ internalIp, "32" }));
172 List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
173 instructions.add(new InstructionInfo(InstructionType.write_metadata, new BigInteger[] { BigInteger.valueOf
174 (routerId), MetaDataUtil.METADATA_MASK_VRFID }));
175 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
176 instructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { NatConstants.DNAT_TABLE }));
178 String flowRef = NatUtil.getFlowRef(dpId, NatConstants.PDNAT_TABLE, externalIp);
180 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NatConstants.PDNAT_TABLE, flowRef,
181 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
182 NatConstants.COOKIE_DNAT_TABLE, matches, instructions);
189 private FlowEntity buildDNATFlowEntity(BigInteger dpId, String internalIp, String externalIp, long routerId) {
191 LOG.info("Bulding DNAT Flow entity for ip {} ", externalIp);
193 List<MatchInfo> matches = new ArrayList<MatchInfo>();
194 matches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
195 BigInteger.valueOf(routerId), MetaDataUtil.METADATA_MASK_VRFID }));
197 matches.add(new MatchInfo(MatchFieldType.eth_type,
198 new long[] { 0x0800L }));
200 matches.add(new MatchInfo(MatchFieldType.ipv4_destination, new String[] {
201 // externalIp, "32" }));
202 internalIp, "32" }));
204 List<ActionInfo> actionsInfos = new ArrayList<ActionInfo>();
205 // actionsInfos.add(new ActionInfo(ActionType.set_destination_ip, new String[]{ internalIp, "32" }));
207 List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
208 // instructions.add(new InstructionInfo(InstructionType.write_metadata, new BigInteger[] { BigInteger.valueOf
209 // (routerId), MetaDataUtil.METADATA_MASK_VRFID }));
210 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] { Integer.toString(NatConstants.L3_FIB_TABLE) }));
211 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
212 //instructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { NatConstants.L3_FIB_TABLE }));
214 String flowRef = NatUtil.getFlowRef(dpId, NatConstants.DNAT_TABLE, externalIp);
216 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NatConstants.DNAT_TABLE, flowRef,
217 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
218 NatConstants.COOKIE_DNAT_TABLE, matches, instructions);
224 private FlowEntity buildPreSNATFlowEntity(BigInteger dpId, String internalIp, String externalIp, long vpnId, long routerId) {
226 LOG.info("Building PSNAT Flow entity for ip {} ", internalIp);
228 List<MatchInfo> matches = new ArrayList<MatchInfo>();
229 matches.add(new MatchInfo(MatchFieldType.eth_type,
230 new long[] { 0x0800L }));
232 matches.add(new MatchInfo(MatchFieldType.ipv4_source, new String[] {
233 internalIp, "32" }));
235 matches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
236 BigInteger.valueOf(routerId), MetaDataUtil.METADATA_MASK_VRFID }));
238 List<ActionInfo> actionsInfos = new ArrayList<ActionInfo>();
239 actionsInfos.add(new ActionInfo(ActionType.set_source_ip, new String[]{ externalIp, "32" }));
241 List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
242 instructions.add(new InstructionInfo(InstructionType.write_metadata, new BigInteger[] { BigInteger.valueOf(vpnId), MetaDataUtil.METADATA_MASK_VRFID }));
243 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
244 instructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { NatConstants.SNAT_TABLE }));
246 String flowRef = NatUtil.getFlowRef(dpId, NatConstants.PSNAT_TABLE, internalIp);
248 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NatConstants.PSNAT_TABLE, flowRef,
249 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
250 NatConstants.COOKIE_DNAT_TABLE, matches, instructions);
255 private FlowEntity buildSNATFlowEntity(BigInteger dpId, String internalIp, String externalIp, long vpnId, String macAddress) {
257 LOG.info("Building SNAT Flow entity for ip {} ", internalIp);
259 List<MatchInfo> matches = new ArrayList<MatchInfo>();
260 matches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
261 BigInteger.valueOf(vpnId), MetaDataUtil.METADATA_MASK_VRFID }));
263 matches.add(new MatchInfo(MatchFieldType.eth_type,
264 new long[] { 0x0800L }));
266 matches.add(new MatchInfo(MatchFieldType.ipv4_source, new String[] {
267 // internalIp, "32" }));
268 externalIp, "32" }));
270 List<ActionInfo> actionsInfos = new ArrayList<ActionInfo>();
271 // actionsInfos.add(new ActionInfo(ActionType.set_source_ip, new String[]{ externalIp, "32" }));
273 //TODO: Set external gateway mac address
274 if(!Strings.isNullOrEmpty(macAddress)) {
275 LOG.debug("Setting ext gw mac address {} in SNAT {} flow action", macAddress, internalIp);
276 actionsInfos.add(new ActionInfo(ActionType.set_field_eth_dest, new String[]{ macAddress }));
279 List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
280 //instructions.add(new InstructionInfo(InstructionType.write_metadata, new BigInteger[] { BigInteger.valueOf(vpnId), MetaDataUtil.METADATA_MASK_VRFID }));
281 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] { Integer.toString(NatConstants.L3_FIB_TABLE) }));
282 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
283 //instructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { NatConstants.L3_FIB_TABLE }));
285 String flowRef = NatUtil.getFlowRef(dpId, NatConstants.SNAT_TABLE, internalIp);
287 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NatConstants.SNAT_TABLE, flowRef,
288 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
289 NatConstants.COOKIE_DNAT_TABLE, matches, instructions);
296 private void createDNATTblEntry(BigInteger dpnId, String internalIp, String externalIp, long routerId, long vpnId) {
297 FlowEntity pFlowEntity = buildPreDNATFlowEntity(dpnId, internalIp, externalIp, routerId, vpnId );
298 mdsalManager.installFlow(pFlowEntity);
300 FlowEntity flowEntity = buildDNATFlowEntity(dpnId, internalIp, externalIp, routerId);
301 mdsalManager.installFlow(flowEntity);
304 private void removeDNATTblEntry(BigInteger dpnId, String internalIp, String externalIp, long routerId) {
305 FlowEntity pFlowEntity = buildPreDNATDeleteFlowEntity(dpnId, internalIp, externalIp, routerId );
306 mdsalManager.removeFlow(pFlowEntity);
308 FlowEntity flowEntity = buildDNATDeleteFlowEntity(dpnId, internalIp, externalIp, routerId);
309 mdsalManager.removeFlow(flowEntity);
312 private void createSNATTblEntry(BigInteger dpnId, String internalIp, String externalIp, long vpnId, long routerId, String macAddress) {
313 FlowEntity pFlowEntity = buildPreSNATFlowEntity(dpnId, internalIp, externalIp, vpnId , routerId);
314 mdsalManager.installFlow(pFlowEntity);
316 FlowEntity flowEntity = buildSNATFlowEntity(dpnId, internalIp, externalIp, vpnId, macAddress);
317 mdsalManager.installFlow(flowEntity);
321 private void removeSNATTblEntry(BigInteger dpnId, String internalIp, String externalIp) {
322 FlowEntity pFlowEntity = buildPreSNATDeleteFlowEntity(dpnId, internalIp, externalIp);
323 mdsalManager.removeFlow(pFlowEntity);
325 FlowEntity flowEntity = buildSNATDeleteFlowEntity(dpnId, internalIp, externalIp);
326 mdsalManager.removeFlow(flowEntity);
330 private Uuid getExtNetworkId(final InstanceIdentifier<RouterPorts> pIdentifier) {
331 Optional<RouterPorts> rtrPort = NatUtil.read(broker, LogicalDatastoreType.CONFIGURATION, pIdentifier);
332 if(!rtrPort.isPresent()) {
333 LOG.error("Unable to read router port entry for {}", pIdentifier);
337 Uuid extNwId = rtrPort.get().getExternalNetworkId();
341 private long getVpnId(Uuid extNwId) {
342 InstanceIdentifier<Networks> nwId = InstanceIdentifier.builder(ExternalNetworks.class).child(Networks.class, new NetworksKey(extNwId)).build();
343 Optional<Networks> nw = NatUtil.read(broker, LogicalDatastoreType.CONFIGURATION, nwId);
344 if(!nw.isPresent()) {
345 LOG.error("Unable to read external network for {}", extNwId);
346 return NatConstants.INVALID_ID;
349 Uuid vpnUuid = nw.get().getVpnid();
350 if(vpnUuid == null) {
351 return NatConstants.INVALID_ID;
354 //Get the id using the VPN UUID (also vpn instance name)
355 return NatUtil.readVpnId(broker, vpnUuid.getValue());
359 private void processFloatingIPAdd(final InstanceIdentifier<IpMapping> identifier,
360 final IpMapping mapping) {
361 LOG.trace("Add event - key: {}, value: {}", identifier, mapping);
363 final String routerId = identifier.firstKeyOf(RouterPorts.class).getRouterId();
364 final PortsKey pKey = identifier.firstKeyOf(Ports.class);
365 String interfaceName = pKey.getPortName();
367 InstanceIdentifier<RouterPorts> pIdentifier = identifier.firstIdentifierOf(RouterPorts.class);
368 createNATFlowEntries(interfaceName, mapping, pIdentifier, routerId);
371 private void processFloatingIPDel(final InstanceIdentifier<IpMapping> identifier,
372 final IpMapping mapping) {
373 LOG.trace("Del event - key: {}, value: {}", identifier, mapping);
375 final String routerId = identifier.firstKeyOf(RouterPorts.class).getRouterId();
376 final PortsKey pKey = identifier.firstKeyOf(Ports.class);
377 String interfaceName = pKey.getPortName();
379 InstanceIdentifier<RouterPorts> pIdentifier = identifier.firstIdentifierOf(RouterPorts.class);
380 removeNATFlowEntries(interfaceName, mapping, pIdentifier, routerId);
383 private InetAddress getInetAddress(String ipAddr) {
384 InetAddress ipAddress = null;
386 ipAddress = InetAddress.getByName(ipAddr);
387 } catch (UnknownHostException e) {
388 LOG.error("UnknowHostException for ip {}", ipAddr);
393 private boolean validateIpMapping(IpMapping mapping) {
394 return getInetAddress(mapping.getInternalIp()) != null &&
395 getInetAddress(mapping.getExternalIp()) != null;
398 void createNATFlowEntries(String interfaceName, final IpMapping mapping,
399 final InstanceIdentifier<RouterPorts> pIdentifier, final String routerName) {
400 if(!validateIpMapping(mapping)) {
401 LOG.warn("Not a valid ip addresses in the mapping {}", mapping);
405 //Get the DPN on which this interface resides
406 BigInteger dpnId = getDpnForInterface(interfaceManager, interfaceName);
408 if(dpnId.equals(BigInteger.ZERO)) {
409 LOG.error("No DPN for interface {}. NAT flow entries for ip mapping {} will not be installed",
410 interfaceName, mapping);
414 long routerId = NatUtil.getVpnId(broker, routerName);
415 if(routerId == NatConstants.INVALID_ID) {
416 LOG.warn("Could not retrieve router id for {} to create NAT Flow entries", routerName);
420 Uuid extNwId = getExtNetworkId(pIdentifier);
421 if(extNwId == null) {
422 LOG.error("External network associated with interface {} could not be retrieved", interfaceName);
423 LOG.error("NAT flow entries will not be installed {}", mapping);
426 long vpnId = getVpnId(extNwId);
428 LOG.error("No VPN associated with Ext nw {}. Unable to create SNAT table entry for fixed ip {}",
429 extNwId, mapping.getInternalIp());
433 //Create the DNAT and SNAT table entries
434 createDNATTblEntry(dpnId, mapping.getInternalIp(), mapping.getExternalIp(), routerId, vpnId);
437 String macAddr = getExternalGatewayMacAddress(routerName);
438 createSNATTblEntry(dpnId, mapping.getInternalIp(), mapping.getExternalIp(), vpnId, routerId, macAddr);
440 handler.onAddFloatingIp(dpnId, routerName, extNwId, interfaceName, mapping.getExternalIp(), mapping
444 void createNATFlowEntries(BigInteger dpnId, String interfaceName, String routerName, Uuid externalNetworkId, String internalIp, String externalIp) {
445 long routerId = NatUtil.getVpnId(broker, routerName);
446 if(routerId == NatConstants.INVALID_ID) {
447 LOG.warn("Could not retrieve router id for {} to create NAT Flow entries", routerName);
450 long vpnId = getVpnId(externalNetworkId);
452 LOG.error("Unable to create SNAT table entry for fixed ip {}", internalIp);
455 //Create the DNAT and SNAT table entries
456 createDNATTblEntry(dpnId, internalIp, externalIp, routerId, vpnId);
458 String macAddr = getExternalGatewayMacAddress(routerName);
459 createSNATTblEntry(dpnId, internalIp, externalIp, vpnId, routerId, macAddr);
461 handler.onAddFloatingIp(dpnId, routerName, externalNetworkId, interfaceName, externalIp, internalIp);
464 private String getExternalGatewayMacAddress(String routerName) {
465 InstanceIdentifier<Routers> routersIdentifier = NatUtil.buildRouterIdentifier(routerName);
466 Optional<Routers> optRouters = NatUtil.read(broker, LogicalDatastoreType.CONFIGURATION, routersIdentifier);
467 if(optRouters.isPresent()) {
468 Routers routers = optRouters.get();
469 return routers.getExtGwMacAddress();
474 void removeNATFlowEntries(String interfaceName, final IpMapping mapping,
475 final InstanceIdentifier<RouterPorts> pIdentifier, final String routerName) {
477 //Get the DPN on which this interface resides
478 BigInteger dpnId = getDpnForInterface(interfaceManager, interfaceName);
479 if(dpnId.equals(BigInteger.ZERO)) {
480 LOG.info("Abort processing Floating ip configuration. No DPN for port : {}", interfaceName);
484 long routerId = NatUtil.getVpnId(broker, routerName);
485 if(routerId == NatConstants.INVALID_ID) {
486 LOG.warn("Could not retrieve router id for {} to remove NAT Flow entries", routerName);
490 //Delete the DNAT and SNAT table entries
491 removeDNATTblEntry(dpnId, mapping.getInternalIp(), mapping.getExternalIp(), routerId);
493 // Uuid extNwId = getExtNetworkId(pIdentifier);
494 // if(extNwId == null) {
495 // LOG.error("External network associated with interface {} could not be retrieved", interfaceName);
498 // long vpnId = getVpnId(extNwId);
500 // LOG.error("No VPN associated with ext nw {}. Unable to delete SNAT table entry for fixed ip {}",
501 // extNwId, mapping.getInternalIp());
504 removeSNATTblEntry(dpnId, mapping.getInternalIp(), mapping.getExternalIp());
506 long label = getOperationalIpMapping(routerName, interfaceName, mapping.getInternalIp());
508 LOG.error("Could not retrieve label for prefix {} in router {}", mapping.getInternalIp(), routerId);
511 //Uuid extNwId = getExtNetworkId(pIdentifier);
512 Uuid extNwId = getExternalNetworkForRouter(routerName);
513 if(extNwId == null) {
514 LOG.error("External network associated with router {} could not be retrieved", routerName);
517 handler.onRemoveFloatingIp(dpnId, routerName, extNwId, mapping.getExternalIp(), mapping.getInternalIp(), (int) label);
518 removeOperationalDS(routerName, interfaceName, mapping.getInternalIp(), mapping.getExternalIp());
522 void removeNATFlowEntries(BigInteger dpnId, String interfaceName, String vpnName, String routerName, Uuid externalNetworkId, String internalIp, String externalIp) {
523 long routerId = NatUtil.getVpnId(broker, routerName);
524 if(routerId == NatConstants.INVALID_ID) {
525 LOG.warn("Could not retrieve router id for {} to create NAT Flow entries", routerName);
528 //Delete the DNAT and SNAT table entries
529 removeDNATTblEntry(dpnId, internalIp, externalIp, routerId);
531 // long vpnId = getVpnId(externalNetworkId);
533 // LOG.error("Unable to delete SNAT table entry for fixed ip {}", internalIp);
536 removeSNATTblEntry(dpnId, internalIp, externalIp);
538 long label = getOperationalIpMapping(routerName, interfaceName, internalIp);
540 LOG.error("Could not retrieve label for prefix {} in router {}", internalIp, routerId);
543 //handler.onRemoveFloatingIp(dpnId, routerName, externalNetworkId, externalIp, internalIp, (int)label);
544 ((VpnFloatingIpHandler)handler).cleanupFibEntries(dpnId, vpnName, externalIp, label);
545 removeOperationalDS(routerName, interfaceName, internalIp, externalIp);
548 private long getOperationalIpMapping(String routerId, String interfaceName, String internalIp) {
549 InstanceIdentifier<IpMapping> ipMappingIdentifier = NatUtil.getIpMappingIdentifier(routerId, interfaceName, internalIp);
550 Optional<IpMapping> ipMapping = NatUtil.read(broker, LogicalDatastoreType.OPERATIONAL, ipMappingIdentifier);
551 if(ipMapping.isPresent()) {
552 return ipMapping.get().getLabel();
554 return NatConstants.INVALID_ID;
557 private Uuid getExternalNetworkForRouter(String routerId) {
558 InstanceIdentifier<RouterPorts> identifier = NatUtil.getRouterPortsId(routerId);
559 Optional<RouterPorts> optRouterPorts = NatUtil.read(broker, LogicalDatastoreType.OPERATIONAL, identifier);
560 if(optRouterPorts.isPresent()) {
561 RouterPorts routerPorts = optRouterPorts.get();
562 return routerPorts.getExternalNetworkId();
567 void updateOperationalDS(String routerId, String interfaceName, int label, String internalIp, String externalIp) {
569 LOG.info("Updating operational DS for floating ip config : {} with label {}", internalIp, label);
570 InstanceIdentifier<Ports> portsId = NatUtil.getPortsIdentifier(routerId, interfaceName);
571 Optional<Ports> optPorts = NatUtil.read(broker, LogicalDatastoreType.OPERATIONAL, portsId);
572 IpMapping ipMapping = new IpMappingBuilder().setKey(new IpMappingKey(internalIp)).setInternalIp(internalIp)
573 .setExternalIp(externalIp).setLabel(label).build();
574 if(optPorts.isPresent()) {
575 LOG.debug("Ports {} entry already present. Updating ipmapping for internal ip {}", interfaceName, internalIp);
576 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, portsId.child(IpMapping.class, new IpMappingKey(internalIp)), ipMapping);
578 LOG.debug("Adding Ports entry {} along with ipmapping {}", interfaceName, internalIp);
579 List<IpMapping> ipMappings = new ArrayList<>();
580 ipMappings.add(ipMapping);
581 Ports ports = new PortsBuilder().setKey(new PortsKey(interfaceName)).setPortName(interfaceName).setIpMapping(ipMappings).build();
582 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, portsId, ports);
586 void removeOperationalDS(String routerId, String interfaceName, String internalIp, String externalIp) {
587 LOG.info("Remove operational DS for floating ip config: {}", internalIp);
588 InstanceIdentifier<IpMapping> ipMappingId = NatUtil.getIpMappingIdentifier(routerId, interfaceName, internalIp);
589 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, ipMappingId);
592 private FlowEntity buildPreDNATDeleteFlowEntity(BigInteger dpId, String internalIp, String externalIp, long routerId) {
594 LOG.info("Bulding Delete DNAT Flow entity for ip {} ", externalIp);
596 String flowRef = NatUtil.getFlowRef(dpId, NatConstants.PDNAT_TABLE, externalIp);
598 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NatConstants.PDNAT_TABLE, flowRef,
599 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
600 NatConstants.COOKIE_DNAT_TABLE, null, null);
607 private FlowEntity buildDNATDeleteFlowEntity(BigInteger dpId, String internalIp, String externalIp, long routerId) {
609 LOG.info("Bulding Delete DNAT Flow entity for ip {} ", externalIp);
611 String flowRef = NatUtil.getFlowRef(dpId, NatConstants.DNAT_TABLE, externalIp);
613 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NatConstants.DNAT_TABLE, flowRef,
614 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
615 NatConstants.COOKIE_DNAT_TABLE, null, null);
621 private FlowEntity buildPreSNATDeleteFlowEntity(BigInteger dpId, String internalIp, String externalIp) {
623 LOG.info("Building Delete PSNAT Flow entity for ip {} ", internalIp);
625 String flowRef = NatUtil.getFlowRef(dpId, NatConstants.PSNAT_TABLE, internalIp);
627 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NatConstants.PSNAT_TABLE, flowRef,
628 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
629 NatConstants.COOKIE_DNAT_TABLE, null, null);
634 private FlowEntity buildSNATDeleteFlowEntity(BigInteger dpId, String internalIp, String externalIp) {
636 LOG.info("Building Delete SNAT Flow entity for ip {} ", internalIp);
638 String flowRef = NatUtil.getFlowRef(dpId, NatConstants.SNAT_TABLE, internalIp);
640 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NatConstants.SNAT_TABLE, flowRef,
641 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
642 NatConstants.COOKIE_DNAT_TABLE, null, null);