2 * Copyright © 2016, 2017 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.natservice.internal;
10 import com.google.common.base.Optional;
11 import io.netty.util.concurrent.GlobalEventExecutor;
12 import java.math.BigInteger;
13 import java.net.InetAddress;
14 import java.net.UnknownHostException;
15 import java.util.ArrayList;
16 import java.util.List;
17 import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
21 import org.opendaylight.genius.mdsalutil.ActionInfo;
22 import org.opendaylight.genius.mdsalutil.FlowEntity;
23 import org.opendaylight.genius.mdsalutil.InstructionInfo;
24 import org.opendaylight.genius.mdsalutil.MDSALUtil;
25 import org.opendaylight.genius.mdsalutil.MatchInfo;
26 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
27 import org.opendaylight.genius.mdsalutil.NwConstants;
28 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
29 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
30 import org.opendaylight.genius.mdsalutil.actions.ActionSetDestinationIp;
31 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldEthernetSource;
32 import org.opendaylight.genius.mdsalutil.actions.ActionSetSourceIp;
33 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
34 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
35 import org.opendaylight.genius.mdsalutil.instructions.InstructionWriteMetadata;
36 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
37 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
38 import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Destination;
39 import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Source;
40 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMapBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMapKey;
57 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
58 import org.osgi.framework.BundleContext;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
62 public class FloatingIPListener extends AsyncDataTreeChangeListenerBase<InternalToExternalPortMap, FloatingIPListener>
63 implements AutoCloseable {
64 private static final Logger LOG = LoggerFactory.getLogger(FloatingIPListener.class);
65 private final DataBroker dataBroker;
66 private final IMdsalApiManager mdsalManager;
67 private final OdlInterfaceRpcService interfaceManager;
68 private final IdManagerService idManager;
69 private FloatingIPHandler floatingIPHandler;
72 public FloatingIPListener(final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
73 final OdlInterfaceRpcService interfaceManager,
74 final IdManagerService idManager,
75 final BundleContext bundleContext) {
77 super(InternalToExternalPortMap.class, FloatingIPListener.class);
78 this.dataBroker = dataBroker;
79 this.mdsalManager = mdsalManager;
80 this.interfaceManager = interfaceManager;
81 this.idManager = idManager;
82 GlobalEventExecutor.INSTANCE.execute(new Runnable() {
85 final WaitingServiceTracker<FloatingIPHandler> tracker = WaitingServiceTracker.create(
86 FloatingIPHandler.class, bundleContext);
87 floatingIPHandler = tracker.waitForService(WaitingServiceTracker.FIVE_MINUTES);
88 LOG.info("FloatingIPListener initialized. FloatingIPHandler={}", floatingIPHandler);
94 LOG.info("{} init", getClass().getSimpleName());
95 registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
99 protected InstanceIdentifier<InternalToExternalPortMap> getWildCardPath() {
100 return InstanceIdentifier.create(FloatingIpInfo.class).child(RouterPorts.class).child(Ports.class)
101 .child(InternalToExternalPortMap.class);
105 protected FloatingIPListener getDataTreeChangeListener() {
106 return FloatingIPListener.this;
110 protected void add(final InstanceIdentifier<InternalToExternalPortMap> identifier,
111 final InternalToExternalPortMap mapping) {
112 LOG.trace("FloatingIPListener add ip mapping method - key: " + identifier + ", value=" + mapping );
113 processFloatingIPAdd(identifier, mapping);
117 protected void remove(InstanceIdentifier<InternalToExternalPortMap> identifier, InternalToExternalPortMap mapping) {
118 LOG.trace("FloatingIPListener remove ip mapping method - key: " + identifier + ", value=" + mapping );
119 processFloatingIPDel(identifier, mapping);
123 protected void update(InstanceIdentifier<InternalToExternalPortMap> identifier, InternalToExternalPortMap
124 original, InternalToExternalPortMap update) {
125 LOG.trace("FloatingIPListener update ip mapping method - key: {}, original: {}, update: {}",
126 identifier, original, update);
129 private FlowEntity buildPreDNATFlowEntity(BigInteger dpId, InternalToExternalPortMap mapping, long routerId, long
131 String externalIp = mapping.getExternalIp();
132 LOG.info("NAT Service : Bulding DNAT Flow entity for ip {} ", externalIp);
133 long segmentId = (associatedVpn == NatConstants.INVALID_ID) ? routerId : associatedVpn;
134 LOG.debug("NAT Service : Segment id {} in build preDNAT Flow", segmentId);
136 List<MatchInfo> matches = new ArrayList<>();
137 matches.add(MatchEthernetType.IPV4);
139 matches.add(new MatchIpv4Destination(externalIp, "32"));
141 // matches.add(new MatchMetadata(
142 // BigInteger.valueOf(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
143 List<ActionInfo> actionsInfos = new ArrayList<>();
144 String internalIp = mapping.getInternalIp();
145 actionsInfos.add(new ActionSetDestinationIp(internalIp, "32"));
147 List<InstructionInfo> instructions = new ArrayList<>();
148 instructions.add(new InstructionWriteMetadata(MetaDataUtil.getVpnIdMetadata(segmentId),
149 MetaDataUtil.METADATA_MASK_VRFID));
150 instructions.add(new InstructionApplyActions(actionsInfos));
151 instructions.add(new InstructionGotoTable(NwConstants.DNAT_TABLE));
153 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.PDNAT_TABLE, routerId, externalIp);
155 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.PDNAT_TABLE, flowRef,
156 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
157 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
162 private FlowEntity buildDNATFlowEntity(BigInteger dpId, InternalToExternalPortMap mapping, long routerId, long
164 String externalIp = mapping.getExternalIp();
165 LOG.info("NAT Service : Bulding DNAT Flow entity for ip {} ", externalIp);
167 long segmentId = (associatedVpn == NatConstants.INVALID_ID) ? routerId : associatedVpn;
168 LOG.debug("NAT Service : Segment id {} in build DNAT", segmentId);
170 List<MatchInfo> matches = new ArrayList<>();
171 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(segmentId), MetaDataUtil.METADATA_MASK_VRFID));
173 matches.add(MatchEthernetType.IPV4);
174 String internalIp = mapping.getInternalIp();
175 matches.add(new MatchIpv4Destination(internalIp, "32"));
177 List<ActionInfo> actionsInfos = new ArrayList<>();
178 // actionsInfos.add(new ActionSetDestinationIp(internalIp, "32"));
180 List<InstructionInfo> instructions = new ArrayList<>();
181 // instructions.add(new InstructionWriteMetadata(BigInteger.valueOf
182 // (routerId), MetaDataUtil.METADATA_MASK_VRFID));
183 actionsInfos.add(new ActionNxResubmit(NwConstants.L3_FIB_TABLE));
184 instructions.add(new InstructionApplyActions(actionsInfos));
185 //instructions.add(new InstructionGotoTable(NatConstants.L3_FIB_TABLE));
187 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.DNAT_TABLE, routerId, internalIp);
189 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.DNAT_TABLE, flowRef,
190 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
191 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
197 private FlowEntity buildPreSNATFlowEntity(BigInteger dpId, String internalIp, String externalIp, long vpnId, long
198 routerId, long associatedVpn) {
200 LOG.info("NAT Service : Building PSNAT Flow entity for ip {} ", internalIp);
202 long segmentId = (associatedVpn == NatConstants.INVALID_ID) ? routerId : associatedVpn;
204 LOG.debug("NAT Service : Segment id {} in build preSNAT flow", segmentId);
206 List<MatchInfo> matches = new ArrayList<>();
207 matches.add(MatchEthernetType.IPV4);
209 matches.add(new MatchIpv4Source(internalIp, "32"));
211 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(segmentId), MetaDataUtil.METADATA_MASK_VRFID));
213 List<ActionInfo> actionsInfos = new ArrayList<>();
214 actionsInfos.add(new ActionSetSourceIp(externalIp, "32"));
216 List<InstructionInfo> instructions = new ArrayList<>();
218 new InstructionWriteMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
219 instructions.add(new InstructionApplyActions(actionsInfos));
220 instructions.add(new InstructionGotoTable(NwConstants.SNAT_TABLE));
222 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.PSNAT_TABLE, routerId, internalIp);
224 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.PSNAT_TABLE, flowRef,
225 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
226 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
231 private FlowEntity buildSNATFlowEntity(BigInteger dpId, InternalToExternalPortMap mapping, long vpnId, Uuid
233 String internalIp = mapping.getInternalIp();
234 LOG.info("Building SNAT Flow entity for ip {} ", internalIp);
236 ProviderTypes provType = NatUtil.getProviderTypefromNetworkId(dataBroker, externalNetworkId);
237 if (provType == null) {
238 LOG.error("NAT Service : Unable to get Network Provider Type for network {}", externalNetworkId);
242 List<MatchInfo> matches = new ArrayList<>();
243 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
245 matches.add(MatchEthernetType.IPV4);
247 String externalIp = mapping.getExternalIp();
248 matches.add(new MatchIpv4Source(externalIp, "32"));
250 List<ActionInfo> actionsInfo = new ArrayList<>();
251 List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
253 Uuid floatingIpId = mapping.getExternalId();
254 String macAddress = NatUtil.getFloatingIpPortMacFromFloatingIpId(dataBroker, floatingIpId);
255 if (macAddress != null) {
256 actionsInfo.add(new ActionSetFieldEthernetSource(new MacAddress(macAddress)));
258 LOG.warn("No MAC address found for floating IP {}", externalIp);
261 if (provType != ProviderTypes.GRE) {
262 Uuid subnetId = NatUtil.getFloatingIpPortSubnetIdFromFloatingIpId(dataBroker, floatingIpId);
263 if (subnetId != null) {
264 long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(subnetId.getValue()), idManager);
265 actionsInfo.add(new ActionGroup(groupId));
267 LOG.warn("No neutron Subnet found for floating IP {}", externalIp);
270 LOG.trace("NAT Service : External Network Provider Type is {}, resubmit to FIB", provType.toString());
271 actionsInfo.add(new ActionNxResubmit(NwConstants.L3_FIB_TABLE));
274 instructions.add(new InstructionApplyActions(actionsInfo));
275 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.SNAT_TABLE, vpnId, externalIp);
277 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.SNAT_TABLE, flowRef,
278 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
279 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
285 private void createDNATTblEntry(BigInteger dpnId, InternalToExternalPortMap mapping, long routerId, long vpnId,
286 long associatedVpnId) {
287 FlowEntity preFlowEntity = buildPreDNATFlowEntity(dpnId, mapping, routerId, associatedVpnId);
288 mdsalManager.installFlow(preFlowEntity);
290 FlowEntity flowEntity = buildDNATFlowEntity(dpnId, mapping, routerId, associatedVpnId);
291 mdsalManager.installFlow(flowEntity);
294 private void removeDNATTblEntry(BigInteger dpnId, String internalIp, String externalIp, long routerId) {
295 FlowEntity preFlowEntity = buildPreDNATDeleteFlowEntity(dpnId, externalIp, routerId);
296 mdsalManager.removeFlow(preFlowEntity);
298 FlowEntity flowEntity = buildDNATDeleteFlowEntity(dpnId, internalIp, routerId);
299 mdsalManager.removeFlow(flowEntity);
302 private void createSNATTblEntry(BigInteger dpnId, InternalToExternalPortMap mapping, long vpnId, long routerId,
303 long associatedVpnId, Uuid externalNetworkId) {
304 FlowEntity preFlowEntity = buildPreSNATFlowEntity(dpnId, mapping.getInternalIp(), mapping.getExternalIp(),
305 vpnId, routerId, associatedVpnId);
306 mdsalManager.installFlow(preFlowEntity);
308 FlowEntity flowEntity = buildSNATFlowEntity(dpnId, mapping, vpnId, externalNetworkId);
309 mdsalManager.installFlow(flowEntity);
312 private void removeSNATTblEntry(BigInteger dpnId, String internalIp, String externalIp, long routerId, long vpnId) {
313 FlowEntity preFlowEntity = buildPreSNATDeleteFlowEntity(dpnId, internalIp, routerId);
314 mdsalManager.removeFlow(preFlowEntity);
316 FlowEntity flowEntity = buildSNATDeleteFlowEntity(dpnId, externalIp, vpnId);
317 mdsalManager.removeFlow(flowEntity);
320 private Uuid getExtNetworkId(final InstanceIdentifier<RouterPorts> portIid,
321 LogicalDatastoreType dataStoreType) {
322 Optional<RouterPorts> rtrPort = NatUtil.read(dataBroker, dataStoreType, portIid);
323 if (!rtrPort.isPresent()) {
324 LOG.error("NAT Service : Unable to read router port entry for {}", portIid);
328 Uuid extNwId = rtrPort.get().getExternalNetworkId();
332 private long getVpnId(Uuid extNwId) {
333 InstanceIdentifier<Networks> nwId = InstanceIdentifier.builder(ExternalNetworks.class).child(Networks.class,
334 new NetworksKey(extNwId)).build();
335 Optional<Networks> nw = NatUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, nwId);
336 if (!nw.isPresent()) {
337 LOG.error("NAT Service : Unable to read external network for {}", extNwId);
338 return NatConstants.INVALID_ID;
341 Uuid vpnUuid = nw.get().getVpnid();
342 if (vpnUuid == null) {
343 return NatConstants.INVALID_ID;
346 //Get the id using the VPN UUID (also vpn instance name)
347 return NatUtil.readVpnId(dataBroker, vpnUuid.getValue());
350 private void processFloatingIPAdd(final InstanceIdentifier<InternalToExternalPortMap> identifier,
351 final InternalToExternalPortMap mapping) {
352 LOG.trace("Add event - key: {}, value: {}", identifier, mapping);
354 final String routerId = identifier.firstKeyOf(RouterPorts.class).getRouterId();
355 final PortsKey pKey = identifier.firstKeyOf(Ports.class);
356 String interfaceName = pKey.getPortName();
358 InstanceIdentifier<RouterPorts> portIid = identifier.firstIdentifierOf(RouterPorts.class);
359 createNATFlowEntries(interfaceName, mapping, portIid, routerId);
362 private void processFloatingIPDel(final InstanceIdentifier<InternalToExternalPortMap> identifier,
363 final InternalToExternalPortMap mapping) {
364 LOG.trace("Del event - key: {}, value: {}", identifier, mapping);
366 final String routerId = identifier.firstKeyOf(RouterPorts.class).getRouterId();
367 final PortsKey pKey = identifier.firstKeyOf(Ports.class);
368 String interfaceName = pKey.getPortName();
370 InstanceIdentifier<RouterPorts> portIid = identifier.firstIdentifierOf(RouterPorts.class);
371 removeNATFlowEntries(interfaceName, mapping, portIid, routerId, null);
374 private InetAddress getInetAddress(String ipAddr) {
375 InetAddress ipAddress = null;
377 ipAddress = InetAddress.getByName(ipAddr);
378 } catch (UnknownHostException e) {
379 LOG.error("NAT Service : UnknowHostException for ip {}", ipAddr);
384 private boolean validateIpMapping(InternalToExternalPortMap mapping) {
385 return getInetAddress(mapping.getInternalIp()) != null && getInetAddress(mapping.getExternalIp()) != null;
388 void createNATFlowEntries(String interfaceName, final InternalToExternalPortMap mapping,
389 final InstanceIdentifier<RouterPorts> portIid, final String routerName) {
390 if (!validateIpMapping(mapping)) {
391 LOG.warn("NAT Service : Not a valid ip addresses in the mapping {}", mapping);
395 //Get the DPN on which this interface resides
396 BigInteger dpnId = NatUtil.getDpnForInterface(interfaceManager, interfaceName);
398 if (dpnId.equals(BigInteger.ZERO)) {
399 LOG.error("NAT Service : No DPN for interface {}. NAT flow entries for ip mapping {} will "
400 + "not be installed", interfaceName, mapping);
404 long routerId = NatUtil.getVpnId(dataBroker, routerName);
405 if (routerId == NatConstants.INVALID_ID) {
406 LOG.warn("NAT Service : Could not retrieve router id for {} to create NAT Flow entries", routerName);
409 //Check if the router to vpn association is present
410 //long associatedVpnId = NatUtil.getAssociatedVpn(dataBroker, routerName);
411 Uuid associatedVpn = NatUtil.getVpnForRouter(dataBroker, routerName);
412 long associatedVpnId = NatConstants.INVALID_ID;
413 if (associatedVpn == null) {
414 LOG.debug("NAT Service : Router {} is not assicated with any BGP VPN instance", routerName);
416 LOG.debug("NAT Service : Router {} is associated with VPN Instance with Id {}", routerName, associatedVpn);
417 associatedVpnId = NatUtil.getVpnId(dataBroker, associatedVpn.getValue());
418 LOG.debug("NAT Service : vpninstance Id is {} for VPN {}", associatedVpnId, associatedVpn);
419 //routerId = associatedVpnId;
422 Uuid extNwId = getExtNetworkId(portIid, LogicalDatastoreType.CONFIGURATION);
423 if (extNwId == null) {
424 LOG.error("NAT Service : External network associated with interface {} could not be retrieved",
426 LOG.error("NAT Service : NAT flow entries will not be installed {}", mapping);
429 long vpnId = getVpnId(extNwId);
431 LOG.error("NAT Service : No VPN associated with Ext nw {}. Unable to create SNAT table entry "
432 + "for fixed ip {}", extNwId, mapping.getInternalIp());
436 //Create the DNAT and SNAT table entries
437 createDNATTblEntry(dpnId, mapping, routerId, vpnId, associatedVpnId);
440 createSNATTblEntry(dpnId, mapping, vpnId, routerId, associatedVpnId, extNwId);
442 floatingIPHandler.onAddFloatingIp(dpnId, routerName, extNwId, interfaceName, mapping);
445 void createNATFlowEntries(BigInteger dpnId, String interfaceName, String routerName, Uuid externalNetworkId,
446 InternalToExternalPortMap mapping) {
447 String internalIp = mapping.getInternalIp();
448 long routerId = NatUtil.getVpnId(dataBroker, routerName);
449 if (routerId == NatConstants.INVALID_ID) {
450 LOG.warn("NAT Service : Could not retrieve router id for {} to create NAT Flow entries", routerName);
453 //Check if the router to vpn association is present
454 long associatedVpnId = NatUtil.getAssociatedVpn(dataBroker, routerName);
455 if (associatedVpnId == NatConstants.INVALID_ID) {
456 LOG.debug("NAT Service : Router {} is not assicated with any BGP VPN instance", routerName);
458 LOG.debug("NAT Service : Router {} is associated with VPN Instance with Id {}",
459 routerName, associatedVpnId);
460 //routerId = associatedVpnId;
463 long vpnId = getVpnId(externalNetworkId);
465 LOG.error("NAT Service : Unable to create SNAT table entry for fixed ip {}", internalIp);
468 //Create the DNAT and SNAT table entries
469 createDNATTblEntry(dpnId, mapping, routerId, vpnId, associatedVpnId);
471 createSNATTblEntry(dpnId, mapping, vpnId, routerId, associatedVpnId, externalNetworkId);
473 floatingIPHandler.onAddFloatingIp(dpnId, routerName, externalNetworkId, interfaceName, mapping);
476 void createNATOnlyFlowEntries(BigInteger dpnId, String routerName, String associatedVPN,
477 Uuid externalNetworkId, InternalToExternalPortMap mapping) {
478 String internalIp = mapping.getInternalIp();
479 //String segmentId = associatedVPN == null ? routerName : associatedVPN;
480 LOG.debug("NAT Service : Retrieving vpn id for VPN {} to proceed with create NAT Flows", routerName);
481 long routerId = NatUtil.getVpnId(dataBroker, routerName);
482 if (routerId == NatConstants.INVALID_ID) {
483 LOG.warn("Could not retrieve vpn id for {} to create NAT Flow entries", routerName);
486 long associatedVpnId = NatUtil.getVpnId(dataBroker, associatedVPN);
487 LOG.debug("NAT Service : Associated VPN Id {} for router {}", associatedVpnId, routerName);
488 long vpnId = getVpnId(externalNetworkId);
490 LOG.error("NAT Service : Unable to create SNAT table entry for fixed ip {}", internalIp);
493 //Create the DNAT and SNAT table entries
494 FlowEntity preFlowEntity = buildPreDNATFlowEntity(dpnId, mapping, routerId, associatedVpnId );
495 mdsalManager.installFlow(preFlowEntity);
497 FlowEntity flowEntity = buildDNATFlowEntity(dpnId, mapping, routerId, associatedVpnId);
498 mdsalManager.installFlow(flowEntity);
500 String externalIp = mapping.getExternalIp();
501 preFlowEntity = buildPreSNATFlowEntity(dpnId, internalIp, externalIp, vpnId , routerId, associatedVpnId);
502 mdsalManager.installFlow(preFlowEntity);
504 flowEntity = buildSNATFlowEntity(dpnId, mapping, vpnId, externalNetworkId);
505 mdsalManager.installFlow(flowEntity);
509 void removeNATFlowEntries(String interfaceName, final InternalToExternalPortMap mapping,
510 InstanceIdentifier<RouterPorts> portIid, final String routerName, BigInteger dpnId) {
511 String internalIp = mapping.getInternalIp();
512 String externalIp = mapping.getExternalIp();
513 //Get the DPN on which this interface resides
515 dpnId = NatUtil.getDpnForInterface(interfaceManager, interfaceName);
516 if (dpnId.equals(BigInteger.ZERO)) {
517 LOG.info("NAT Service: Abort processing Floating ip configuration. No DPN for port: {}", interfaceName);
522 long routerId = NatUtil.getVpnId(dataBroker, routerName);
523 if (routerId == NatConstants.INVALID_ID) {
524 LOG.warn("NAT Service : Could not retrieve router id for {} to remove NAT Flow entries", routerName);
528 //Delete the DNAT and SNAT table entries
529 removeDNATTblEntry(dpnId, internalIp, externalIp, routerId);
531 Uuid extNwId = getExtNetworkId(portIid, LogicalDatastoreType.OPERATIONAL);
532 if (extNwId == null) {
533 LOG.error("NAT Service : External network associated with interface {} could not be retrieved",
537 long vpnId = getVpnId(extNwId);
539 LOG.error("NAT Service : No VPN associated with ext nw {}. Unable to delete SNAT table "
540 + "entry for fixed ip {}", extNwId, internalIp);
543 removeSNATTblEntry(dpnId, internalIp, externalIp, routerId, vpnId);
545 long label = getOperationalIpMapping(routerName, interfaceName, internalIp);
547 LOG.error("NAT Service : Could not retrieve label for prefix {} in router {}", internalIp, routerId);
550 floatingIPHandler.onRemoveFloatingIp(dpnId, routerName, extNwId, mapping, (int) label);
551 removeOperationalDS(routerName, interfaceName, internalIp, externalIp);
554 void removeNATFlowEntries(BigInteger dpnId, String interfaceName, String vpnName, String routerName,
555 InternalToExternalPortMap mapping) {
556 String internalIp = mapping.getInternalIp();
557 String externalIp = mapping.getExternalIp();
558 long routerId = NatUtil.getVpnId(dataBroker, routerName);
559 if (routerId == NatConstants.INVALID_ID) {
560 LOG.warn("NAT Service : Could not retrieve router id for {} to remove NAT Flow entries", routerName);
564 long vpnId = NatUtil.getVpnId(dataBroker, vpnName);
565 if (vpnId == NatConstants.INVALID_ID) {
566 LOG.warn("NAT Service : VPN Id not found for {} to remove NAT flow entries {}", vpnName, internalIp);
569 //Delete the DNAT and SNAT table entries
570 removeDNATTblEntry(dpnId, internalIp, externalIp, routerId);
572 removeSNATTblEntry(dpnId, internalIp, externalIp, routerId, vpnId);
574 long label = getOperationalIpMapping(routerName, interfaceName, internalIp);
576 LOG.error("NAT Service : Could not retrieve label for prefix {} in router {}", internalIp, routerId);
579 floatingIPHandler.cleanupFibEntries(dpnId, vpnName, externalIp, label);
580 removeOperationalDS(routerName, interfaceName, internalIp, externalIp);
583 protected long getOperationalIpMapping(String routerId, String interfaceName, String internalIp) {
584 InstanceIdentifier<InternalToExternalPortMap> intExtPortMapIdentifier =
585 NatUtil.getIntExtPortMapIdentifier(routerId, interfaceName, internalIp);
586 Optional<InternalToExternalPortMap> intExtPortMap = NatUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
587 intExtPortMapIdentifier);
588 if (intExtPortMap.isPresent()) {
589 return intExtPortMap.get().getLabel();
591 return NatConstants.INVALID_ID;
594 void updateOperationalDS(String routerId, String interfaceName, long label, String internalIp, String externalIp) {
596 LOG.info("NAT Service : Updating operational DS for floating ip config : {} with label {}", internalIp, label);
597 InstanceIdentifier<Ports> portsId = NatUtil.getPortsIdentifier(routerId, interfaceName);
598 Optional<Ports> optPorts = NatUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, portsId);
599 InternalToExternalPortMap intExtPortMap = new InternalToExternalPortMapBuilder().setKey(new
600 InternalToExternalPortMapKey(internalIp)).setInternalIp(internalIp).setExternalIp(externalIp)
601 .setLabel(label).build();
602 if (optPorts.isPresent()) {
603 LOG.debug("Ports {} entry already present. Updating intExtPortMap for internal ip {}", interfaceName,
605 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, portsId.child(InternalToExternalPortMap
606 .class, new InternalToExternalPortMapKey(internalIp)), intExtPortMap);
608 LOG.debug("Adding Ports entry {} along with intExtPortMap {}", interfaceName, internalIp);
609 List<InternalToExternalPortMap> intExtPortMapList = new ArrayList<>();
610 intExtPortMapList.add(intExtPortMap);
611 Ports ports = new PortsBuilder().setKey(new PortsKey(interfaceName)).setPortName(interfaceName)
612 .setInternalToExternalPortMap(intExtPortMapList).build();
613 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, portsId, ports);
617 void removeOperationalDS(String routerId, String interfaceName, String internalIp, String externalIp) {
618 LOG.info("Remove operational DS for floating ip config: {}", internalIp);
619 InstanceIdentifier<InternalToExternalPortMap> intExtPortMapId = NatUtil.getIntExtPortMapIdentifier(routerId,
620 interfaceName, internalIp);
621 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, intExtPortMapId);
624 private FlowEntity buildPreDNATDeleteFlowEntity(BigInteger dpId, String externalIp, long routerId) {
626 LOG.info("NAT Service : Bulding Delete DNAT Flow entity for ip {} ", externalIp);
628 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.PDNAT_TABLE, routerId, externalIp);
630 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.PDNAT_TABLE, flowRef,
631 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
632 NwConstants.COOKIE_DNAT_TABLE, null, null);
639 private FlowEntity buildDNATDeleteFlowEntity(BigInteger dpId, String internalIp, long routerId) {
641 LOG.info("NAT Service : Bulding Delete DNAT Flow entity for ip {} ", internalIp);
643 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.DNAT_TABLE, routerId, internalIp);
645 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.DNAT_TABLE, flowRef,
646 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
647 NwConstants.COOKIE_DNAT_TABLE, null, null);
653 private FlowEntity buildPreSNATDeleteFlowEntity(BigInteger dpId, String internalIp, long routerId) {
655 LOG.info("NAT Service : Building Delete PSNAT Flow entity for ip {} ", internalIp);
657 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.PSNAT_TABLE, routerId, internalIp);
659 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.PSNAT_TABLE, flowRef,
660 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
661 NwConstants.COOKIE_DNAT_TABLE, null, null);
665 private FlowEntity buildSNATDeleteFlowEntity(BigInteger dpId, String externalIp, long routerId) {
667 LOG.info("NAT Service : Building Delete SNAT Flow entity for ip {} ", externalIp);
669 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.SNAT_TABLE, routerId, externalIp);
671 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.SNAT_TABLE, flowRef,
672 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
673 NwConstants.COOKIE_DNAT_TABLE, null, null);