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.netvirt.natservice.internal;
10 import io.netty.util.concurrent.GlobalEventExecutor;
12 import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
15 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.genius.mdsalutil.AbstractDataChangeListener;
18 import org.opendaylight.genius.mdsalutil.ActionInfo;
19 import org.opendaylight.genius.mdsalutil.ActionType;
20 import org.opendaylight.genius.mdsalutil.FlowEntity;
21 import org.opendaylight.genius.mdsalutil.InstructionInfo;
22 import org.opendaylight.genius.mdsalutil.InstructionType;
23 import org.opendaylight.genius.mdsalutil.MatchFieldType;
24 import org.opendaylight.genius.mdsalutil.MatchInfo;
25 import org.opendaylight.genius.mdsalutil.MDSALUtil;
26 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
27 import org.opendaylight.genius.mdsalutil.NwConstants;
28 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.IpMapping;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.IpMappingBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.IpMappingKey;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
41 import org.opendaylight.yangtools.concepts.ListenerRegistration;
42 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
43 import org.osgi.framework.BundleContext;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
52 import com.google.common.base.Optional;
54 import java.math.BigInteger;
55 import java.net.InetAddress;
56 import java.net.UnknownHostException;
57 import java.util.ArrayList;
58 import java.util.List;
60 public class FloatingIPListener extends AbstractDataChangeListener<IpMapping> implements AutoCloseable{
61 private static final Logger LOG = LoggerFactory.getLogger(FloatingIPListener.class);
62 private ListenerRegistration<DataChangeListener> listenerRegistration;
63 private final DataBroker dataBroker;
64 private final IMdsalApiManager mdsalManager;
65 private final OdlInterfaceRpcService interfaceManager;
66 private final IdManagerService idManager;
67 private FloatingIPHandler floatingIPHandler;
70 public FloatingIPListener(final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
71 final OdlInterfaceRpcService interfaceManager,
72 final IdManagerService idManager,
73 final BundleContext bundleContext) {
74 super(IpMapping.class);
75 this.dataBroker = dataBroker;
76 this.mdsalManager = mdsalManager;
77 this.interfaceManager = interfaceManager;
78 this.idManager = idManager;
80 GlobalEventExecutor.INSTANCE.execute(new Runnable() {
83 final WaitingServiceTracker<FloatingIPHandler> tracker = WaitingServiceTracker.create(
84 FloatingIPHandler.class, bundleContext);
85 floatingIPHandler = tracker.waitForService(WaitingServiceTracker.FIVE_MINUTES);
86 LOG.info("FloatingIPListener initialized. FloatingIPHandler={}", floatingIPHandler);
92 LOG.info("{} init", getClass().getSimpleName());
93 listenerRegistration = dataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
94 getWildCardPath(), this, AsyncDataBroker.DataChangeScope.SUBTREE);
97 private InstanceIdentifier<IpMapping> getWildCardPath() {
98 return InstanceIdentifier.create(FloatingIpInfo.class).child(RouterPorts.class).child(Ports.class)
99 .child(IpMapping.class);
103 public void close() throws Exception {
104 if (listenerRegistration != null) {
105 listenerRegistration.close();
106 listenerRegistration = null;
108 LOG.info("{} close", getClass().getSimpleName());
112 protected void add(final InstanceIdentifier<IpMapping> identifier,
113 final IpMapping mapping) {
114 LOG.trace("FloatingIPListener add ip mapping method - key: " + identifier + ", value=" + mapping );
115 processFloatingIPAdd(identifier, mapping);
119 protected void remove(InstanceIdentifier<IpMapping> identifier, IpMapping mapping) {
120 LOG.trace("FloatingIPListener remove ip mapping method - key: " + identifier + ", value=" + mapping );
121 processFloatingIPDel(identifier, mapping);
125 protected void update(InstanceIdentifier<IpMapping> identifier, IpMapping original, IpMapping update) {
126 LOG.trace("FloatingIPListener update ip mapping method - key: " + identifier + ", original=" + original + ", update=" + update );
129 private FlowEntity buildPreDNATFlowEntity(BigInteger dpId, String internalIp, String externalIp, long routerId, long vpnId, long associatedVpn) {
130 LOG.info("Bulding DNAT Flow entity for ip {} ", externalIp);
132 long segmentId = (associatedVpn == NatConstants.INVALID_ID) ? routerId : associatedVpn;
133 LOG.debug("Segment id {} in build preDNAT Flow", segmentId);
135 List<MatchInfo> matches = new ArrayList<>();
136 matches.add(new MatchInfo(MatchFieldType.eth_type,
137 new long[] { 0x0800L }));
139 matches.add(new MatchInfo(MatchFieldType.ipv4_destination, new String[] {
140 externalIp, "32" }));
142 // matches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
143 // BigInteger.valueOf(vpnId), MetaDataUtil.METADATA_MASK_VRFID }));
145 List<ActionInfo> actionsInfos = new ArrayList<>();
146 actionsInfos.add(new ActionInfo(ActionType.set_destination_ip, new String[]{ internalIp, "32" }));
148 List<InstructionInfo> instructions = new ArrayList<>();
149 instructions.add(new InstructionInfo(InstructionType.write_metadata,
150 new BigInteger[] { MetaDataUtil.getVpnIdMetadata(segmentId), MetaDataUtil.METADATA_MASK_VRFID }));
151 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
152 instructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { NwConstants.DNAT_TABLE }));
154 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.PDNAT_TABLE, routerId, externalIp);
156 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.PDNAT_TABLE, flowRef,
157 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
158 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
163 private FlowEntity buildDNATFlowEntity(BigInteger dpId, String internalIp, String externalIp, long routerId, long associatedVpn) {
165 LOG.info("Bulding DNAT Flow entity for ip {} ", externalIp);
167 long segmentId = (associatedVpn == NatConstants.INVALID_ID) ? routerId : associatedVpn;
168 LOG.debug("Segment id {} in build DNAT", segmentId);
170 List<MatchInfo> matches = new ArrayList<>();
171 matches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
172 MetaDataUtil.getVpnIdMetadata(segmentId), MetaDataUtil.METADATA_MASK_VRFID }));
174 matches.add(new MatchInfo(MatchFieldType.eth_type,
175 new long[] { 0x0800L }));
177 matches.add(new MatchInfo(MatchFieldType.ipv4_destination, new String[] {
178 // externalIp, "32" }));
179 internalIp, "32" }));
181 List<ActionInfo> actionsInfos = new ArrayList<>();
182 // actionsInfos.add(new ActionInfo(ActionType.set_destination_ip, new String[]{ internalIp, "32" }));
184 List<InstructionInfo> instructions = new ArrayList<>();
185 // instructions.add(new InstructionInfo(InstructionType.write_metadata, new BigInteger[] { BigInteger.valueOf
186 // (routerId), MetaDataUtil.METADATA_MASK_VRFID }));
187 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] { Integer.toString(NwConstants.L3_FIB_TABLE) }));
188 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
189 //instructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { NatConstants.L3_FIB_TABLE }));
191 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.DNAT_TABLE, routerId, externalIp);
193 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.DNAT_TABLE, flowRef,
194 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
195 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
201 private FlowEntity buildPreSNATFlowEntity(BigInteger dpId, String internalIp, String externalIp, long vpnId, long routerId, long associatedVpn) {
203 LOG.info("Building PSNAT Flow entity for ip {} ", internalIp);
205 long segmentId = (associatedVpn == NatConstants.INVALID_ID) ? routerId : associatedVpn;
207 LOG.debug("Segment id {} in build preSNAT flow", segmentId);
209 List<MatchInfo> matches = new ArrayList<>();
210 matches.add(new MatchInfo(MatchFieldType.eth_type,
211 new long[] { 0x0800L }));
213 matches.add(new MatchInfo(MatchFieldType.ipv4_source, new String[] {
214 internalIp, "32" }));
216 matches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
217 MetaDataUtil.getVpnIdMetadata(segmentId), MetaDataUtil.METADATA_MASK_VRFID }));
219 List<ActionInfo> actionsInfos = new ArrayList<>();
220 actionsInfos.add(new ActionInfo(ActionType.set_source_ip, new String[]{ externalIp, "32" }));
222 List<InstructionInfo> instructions = new ArrayList<>();
223 instructions.add(new InstructionInfo(InstructionType.write_metadata,
224 new BigInteger[] { MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID }));
225 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
226 instructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { NwConstants.SNAT_TABLE }));
228 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.PSNAT_TABLE, routerId, internalIp);
230 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.PSNAT_TABLE, flowRef,
231 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
232 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
237 private FlowEntity buildSNATFlowEntity(BigInteger dpId, String internalIp, String externalIp, long vpnId) {
238 LOG.info("Building SNAT Flow entity for ip {} ", internalIp);
240 List<MatchInfo> matches = new ArrayList<>();
241 matches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
242 MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID }));
244 matches.add(new MatchInfo(MatchFieldType.eth_type,
245 new long[] { 0x0800L }));
247 matches.add(new MatchInfo(MatchFieldType.ipv4_source, new String[] {
248 externalIp, "32" }));
250 List<ActionInfo> actionsInfo = new ArrayList<>();
251 List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
253 IpAddress externalIpv4Address = new IpAddress(new Ipv4Address(externalIp));
254 Port port = NatUtil.getNeutronPortForFloatingIp(dataBroker, externalIpv4Address);
255 if (port != null && port.getMacAddress() != null) {
256 actionsInfo.add(new ActionInfo(ActionType.set_field_eth_src, new String[] { port.getMacAddress().getValue() }));
258 LOG.warn("No MAC address found for floating IP {}", externalIp);
261 Uuid subnetId = NatUtil.getSubnetIdForFloatingIp(port, externalIpv4Address);
262 if (subnetId != null) {
263 long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(subnetId.getValue()), idManager);
264 actionsInfo.add(new ActionInfo(ActionType.group, new String[] {String.valueOf(groupId)}));
266 LOG.warn("No neutron Subnet found for floating IP {}", externalIp);
269 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfo));
270 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.SNAT_TABLE, vpnId, internalIp);
272 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.SNAT_TABLE, flowRef,
273 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
274 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
279 private void createDNATTblEntry(BigInteger dpnId, String internalIp, String externalIp, long routerId, long vpnId, long associatedVpnId) {
280 FlowEntity pFlowEntity = buildPreDNATFlowEntity(dpnId, internalIp, externalIp, routerId, vpnId, associatedVpnId );
281 mdsalManager.installFlow(pFlowEntity);
283 FlowEntity flowEntity = buildDNATFlowEntity(dpnId, internalIp, externalIp, routerId, associatedVpnId);
284 mdsalManager.installFlow(flowEntity);
287 private void removeDNATTblEntry(BigInteger dpnId, String internalIp, String externalIp, long routerId) {
288 FlowEntity pFlowEntity = buildPreDNATDeleteFlowEntity(dpnId, internalIp, externalIp, routerId );
289 mdsalManager.removeFlow(pFlowEntity);
291 FlowEntity flowEntity = buildDNATDeleteFlowEntity(dpnId, internalIp, externalIp, routerId);
292 mdsalManager.removeFlow(flowEntity);
295 private void createSNATTblEntry(BigInteger dpnId, String internalIp, String externalIp, long vpnId, long routerId, long associatedVpnId) {
296 FlowEntity pFlowEntity = buildPreSNATFlowEntity(dpnId, internalIp, externalIp, vpnId , routerId, associatedVpnId);
297 mdsalManager.installFlow(pFlowEntity);
299 FlowEntity flowEntity = buildSNATFlowEntity(dpnId, internalIp, externalIp, vpnId);
300 mdsalManager.installFlow(flowEntity);
304 private void removeSNATTblEntry(BigInteger dpnId, String internalIp, long routerId, String externalIp, long vpnId) {
305 FlowEntity pFlowEntity = buildPreSNATDeleteFlowEntity(dpnId, internalIp, routerId, externalIp);
306 mdsalManager.removeFlow(pFlowEntity);
308 FlowEntity flowEntity = buildSNATDeleteFlowEntity(dpnId, internalIp, vpnId, externalIp);
309 mdsalManager.removeFlow(flowEntity);
313 private Uuid getExtNetworkId(final InstanceIdentifier<RouterPorts> pIdentifier, LogicalDatastoreType dataStoreType) {
314 Optional<RouterPorts> rtrPort = NatUtil.read(dataBroker, dataStoreType, pIdentifier);
315 if(!rtrPort.isPresent()) {
316 LOG.error("Unable to read router port entry for {}", pIdentifier);
320 Uuid extNwId = rtrPort.get().getExternalNetworkId();
324 private long getVpnId(Uuid extNwId) {
325 InstanceIdentifier<Networks> nwId = InstanceIdentifier.builder(ExternalNetworks.class).child(Networks.class, new NetworksKey(extNwId)).build();
326 Optional<Networks> nw = NatUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, nwId);
327 if(!nw.isPresent()) {
328 LOG.error("Unable to read external network for {}", extNwId);
329 return NatConstants.INVALID_ID;
332 Uuid vpnUuid = nw.get().getVpnid();
333 if(vpnUuid == null) {
334 return NatConstants.INVALID_ID;
337 //Get the id using the VPN UUID (also vpn instance name)
338 return NatUtil.readVpnId(dataBroker, vpnUuid.getValue());
341 private void processFloatingIPAdd(final InstanceIdentifier<IpMapping> identifier,
342 final IpMapping mapping) {
343 LOG.trace("Add event - key: {}, value: {}", identifier, mapping);
345 final String routerId = identifier.firstKeyOf(RouterPorts.class).getRouterId();
346 final PortsKey pKey = identifier.firstKeyOf(Ports.class);
347 String interfaceName = pKey.getPortName();
349 InstanceIdentifier<RouterPorts> pIdentifier = identifier.firstIdentifierOf(RouterPorts.class);
350 createNATFlowEntries(interfaceName, mapping, pIdentifier, routerId);
353 private void processFloatingIPDel(final InstanceIdentifier<IpMapping> identifier,
354 final IpMapping mapping) {
355 LOG.trace("Del event - key: {}, value: {}", identifier, mapping);
357 final String routerId = identifier.firstKeyOf(RouterPorts.class).getRouterId();
358 final PortsKey pKey = identifier.firstKeyOf(Ports.class);
359 String interfaceName = pKey.getPortName();
361 InstanceIdentifier<RouterPorts> pIdentifier = identifier.firstIdentifierOf(RouterPorts.class);
362 removeNATFlowEntries(interfaceName, mapping, pIdentifier, routerId);
365 private InetAddress getInetAddress(String ipAddr) {
366 InetAddress ipAddress = null;
368 ipAddress = InetAddress.getByName(ipAddr);
369 } catch (UnknownHostException e) {
370 LOG.error("UnknowHostException for ip {}", ipAddr);
375 private boolean validateIpMapping(IpMapping mapping) {
376 return getInetAddress(mapping.getInternalIp()) != null &&
377 getInetAddress(mapping.getExternalIp()) != null;
380 void createNATFlowEntries(String interfaceName, final IpMapping mapping,
381 final InstanceIdentifier<RouterPorts> pIdentifier, final String routerName) {
382 if(!validateIpMapping(mapping)) {
383 LOG.warn("Not a valid ip addresses in the mapping {}", mapping);
387 //Get the DPN on which this interface resides
388 BigInteger dpnId = NatUtil.getDpnForInterface(interfaceManager, interfaceName);
390 if(dpnId.equals(BigInteger.ZERO)) {
391 LOG.error("No DPN for interface {}. NAT flow entries for ip mapping {} will not be installed",
392 interfaceName, mapping);
396 long routerId = NatUtil.getVpnId(dataBroker, routerName);
397 if(routerId == NatConstants.INVALID_ID) {
398 LOG.warn("Could not retrieve router id for {} to create NAT Flow entries", routerName);
401 //Check if the router to vpn association is present
402 //long associatedVpnId = NatUtil.getAssociatedVpn(dataBroker, routerName);
403 Uuid associatedVpn = NatUtil.getVpnForRouter(dataBroker, routerName);
404 long associatedVpnId = NatConstants.INVALID_ID;
405 if(associatedVpn == null) {
406 LOG.debug("Router {} is not assicated with any BGP VPN instance", routerName);
408 LOG.debug("Router {} is associated with VPN Instance with Id {}", routerName, associatedVpn);
409 associatedVpnId = NatUtil.getVpnId(dataBroker, associatedVpn.getValue());
410 LOG.debug("vpninstance Id is {} for VPN {}", associatedVpnId, associatedVpn);
411 //routerId = associatedVpnId;
414 Uuid extNwId = getExtNetworkId(pIdentifier, LogicalDatastoreType.CONFIGURATION);
415 if(extNwId == null) {
416 LOG.error("External network associated with interface {} could not be retrieved", interfaceName);
417 LOG.error("NAT flow entries will not be installed {}", mapping);
420 long vpnId = getVpnId(extNwId);
422 LOG.error("No VPN associated with Ext nw {}. Unable to create SNAT table entry for fixed ip {}",
423 extNwId, mapping.getInternalIp());
427 //Create the DNAT and SNAT table entries
428 createDNATTblEntry(dpnId, mapping.getInternalIp(), mapping.getExternalIp(), routerId, vpnId, associatedVpnId);
431 createSNATTblEntry(dpnId, mapping.getInternalIp(), mapping.getExternalIp(), vpnId, routerId, associatedVpnId);
433 floatingIPHandler.onAddFloatingIp(dpnId, routerName, extNwId, interfaceName, mapping.getExternalIp(), mapping
437 void createNATFlowEntries(BigInteger dpnId, String interfaceName, String routerName, Uuid externalNetworkId, String internalIp, String externalIp) {
438 long routerId = NatUtil.getVpnId(dataBroker, routerName);
439 if(routerId == NatConstants.INVALID_ID) {
440 LOG.warn("Could not retrieve router id for {} to create NAT Flow entries", routerName);
443 //Check if the router to vpn association is present
444 long associatedVpnId = NatUtil.getAssociatedVpn(dataBroker, routerName);
445 if(associatedVpnId == NatConstants.INVALID_ID) {
446 LOG.debug("Router {} is not assicated with any BGP VPN instance", routerName);
448 LOG.debug("Router {} is associated with VPN Instance with Id {}", routerName, associatedVpnId);
449 //routerId = associatedVpnId;
452 long vpnId = getVpnId(externalNetworkId);
454 LOG.error("Unable to create SNAT table entry for fixed ip {}", internalIp);
457 //Create the DNAT and SNAT table entries
458 createDNATTblEntry(dpnId, internalIp, externalIp, routerId, vpnId, associatedVpnId);
460 createSNATTblEntry(dpnId, internalIp, externalIp, vpnId, routerId, associatedVpnId);
462 floatingIPHandler.onAddFloatingIp(dpnId, routerName, externalNetworkId, interfaceName, externalIp, internalIp);
465 void createNATOnlyFlowEntries(BigInteger dpnId, String interfaceName, String routerName, String associatedVPN, Uuid externalNetworkId, String internalIp, String externalIp) {
466 //String segmentId = associatedVPN == null ? routerName : associatedVPN;
467 LOG.debug("Retrieving vpn id for VPN {} to proceed with create NAT Flows", routerName);
468 long routerId = NatUtil.getVpnId(dataBroker, routerName);
469 if(routerId == NatConstants.INVALID_ID) {
470 LOG.warn("Could not retrieve vpn id for {} to create NAT Flow entries", routerName);
473 long associatedVpnId = NatUtil.getVpnId(dataBroker, associatedVPN);
474 LOG.debug("Associated VPN Id {} for router {}", associatedVpnId, routerName);
475 long vpnId = getVpnId(externalNetworkId);
477 LOG.error("Unable to create SNAT table entry for fixed ip {}", internalIp);
480 //Create the DNAT and SNAT table entries
481 //createDNATTblEntry(dpnId, internalIp, externalIp, routerId, vpnId);
482 FlowEntity pFlowEntity = buildPreDNATFlowEntity(dpnId, internalIp, externalIp, routerId, vpnId, associatedVpnId );
483 mdsalManager.installFlow(pFlowEntity);
485 FlowEntity flowEntity = buildDNATFlowEntity(dpnId, internalIp, externalIp, routerId, associatedVpnId);
486 mdsalManager.installFlow(flowEntity);
488 //createSNATTblEntry(dpnId, internalIp, externalIp, vpnId, routerId, macAddr);
489 pFlowEntity = buildPreSNATFlowEntity(dpnId, internalIp, externalIp, vpnId , routerId, associatedVpnId);
490 mdsalManager.installFlow(pFlowEntity);
492 flowEntity = buildSNATFlowEntity(dpnId, internalIp, externalIp, vpnId);
493 mdsalManager.installFlow(flowEntity);
497 void removeNATFlowEntries(String interfaceName, final IpMapping mapping,
498 final InstanceIdentifier<RouterPorts> pIdentifier, final String routerName) {
500 //Get the DPN on which this interface resides
501 BigInteger dpnId = NatUtil.getDpnForInterface(interfaceManager, interfaceName);
502 if(dpnId.equals(BigInteger.ZERO)) {
503 LOG.info("Abort processing Floating ip configuration. No DPN for port : {}", interfaceName);
507 long routerId = NatUtil.getVpnId(dataBroker, routerName);
508 if(routerId == NatConstants.INVALID_ID) {
509 LOG.warn("Could not retrieve router id for {} to remove NAT Flow entries", routerName);
512 //if(routerId == NatConstants.INVALID_ID) {
513 //The router could be associated with BGP VPN
514 Uuid associatedVPN = NatUtil.getVpnForRouter(dataBroker, routerName);
515 long associatedVpnId = NatConstants.INVALID_ID;
516 if(associatedVPN == null) {
517 LOG.warn("Could not retrieve router id for {} to remove NAT Flow entries", routerName);
519 LOG.debug("Retrieving vpn id for VPN {} to proceed with remove NAT Flows", associatedVPN.getValue());
520 associatedVpnId = NatUtil.getVpnId(dataBroker, associatedVPN.getValue());
523 //Delete the DNAT and SNAT table entries
524 removeDNATTblEntry(dpnId, mapping.getInternalIp(), mapping.getExternalIp(), routerId);
526 Uuid extNwId = getExtNetworkId(pIdentifier, LogicalDatastoreType.OPERATIONAL);
527 if(extNwId == null) {
528 LOG.error("External network associated with interface {} could not be retrieved", interfaceName);
531 long vpnId = getVpnId(extNwId);
533 LOG.error("No VPN associated with ext nw {}. Unable to delete SNAT table entry for fixed ip {}",
534 extNwId, mapping.getInternalIp());
537 removeSNATTblEntry(dpnId, mapping.getInternalIp(), routerId, mapping.getExternalIp(), vpnId);
539 long label = getOperationalIpMapping(routerName, interfaceName, mapping.getInternalIp());
541 LOG.error("Could not retrieve label for prefix {} in router {}", mapping.getInternalIp(), routerId);
544 //Uuid extNwId = getExtNetworkId(pIdentifier);
545 // Uuid extNwId = getExternalNetworkForRouter(routerName);
546 // if(extNwId == null) {
547 // LOG.error("External network associated with router {} could not be retrieved", routerName);
550 floatingIPHandler.onRemoveFloatingIp(dpnId, routerName, extNwId, mapping.getExternalIp(), mapping.getInternalIp(), (int) label);
551 removeOperationalDS(routerName, interfaceName, mapping.getInternalIp(), mapping.getExternalIp());
555 void removeNATFlowEntries(BigInteger dpnId, String interfaceName, String vpnName, String routerName, Uuid externalNetworkId, String internalIp, String externalIp) {
556 long routerId = NatUtil.getVpnId(dataBroker, routerName);
557 if(routerId == NatConstants.INVALID_ID) {
558 LOG.warn("Could not retrieve router id for {} to remove NAT Flow entries", routerName);
562 long vpnId = NatUtil.getVpnId(dataBroker, vpnName);
563 if(vpnId == NatConstants.INVALID_ID) {
564 LOG.warn("VPN Id not found for {} to remove NAT flow entries {}", vpnName, internalIp);
567 //Delete the DNAT and SNAT table entries
568 removeDNATTblEntry(dpnId, internalIp, externalIp, routerId);
570 removeSNATTblEntry(dpnId, internalIp, routerId, externalIp, vpnId);
572 long label = getOperationalIpMapping(routerName, interfaceName, internalIp);
574 LOG.error("Could not retrieve label for prefix {} in router {}", internalIp, routerId);
577 //floatingIPHandler.onRemoveFloatingIp(dpnId, routerName, externalNetworkId, externalIp, internalIp, (int)label);
578 ((VpnFloatingIpHandler) floatingIPHandler).cleanupFibEntries(dpnId, vpnName, externalIp, label);
579 removeOperationalDS(routerName, interfaceName, internalIp, externalIp);
582 void removeNATOnlyFlowEntries(BigInteger dpnId, String interfaceName, String routerName, String associatedVPN,
583 String internalIp, String externalIp) {
584 String segmentId = associatedVPN == null ? routerName : associatedVPN;
585 LOG.debug("Retrieving vpn id for VPN {} to proceed with remove NAT Flows", segmentId);
586 long routerId = NatUtil.getVpnId(dataBroker, segmentId);
587 if(routerId == NatConstants.INVALID_ID) {
588 LOG.warn("Could not retrieve vpn id for {} to remove NAT Flow entries", segmentId);
591 //Delete the DNAT and SNAT table entries
592 removeDNATTblEntry(dpnId, internalIp, externalIp, routerId);
594 //removeSNATTblEntry(dpnId, internalIp, routerId, externalIp);
597 private long getOperationalIpMapping(String routerId, String interfaceName, String internalIp) {
598 InstanceIdentifier<IpMapping> ipMappingIdentifier = NatUtil.getIpMappingIdentifier(routerId, interfaceName, internalIp);
599 Optional<IpMapping> ipMapping = NatUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, ipMappingIdentifier);
600 if(ipMapping.isPresent()) {
601 return ipMapping.get().getLabel();
603 return NatConstants.INVALID_ID;
606 void updateOperationalDS(String routerId, String interfaceName, long label, String internalIp, String externalIp) {
608 LOG.info("Updating operational DS for floating ip config : {} with label {}", internalIp, label);
609 InstanceIdentifier<Ports> portsId = NatUtil.getPortsIdentifier(routerId, interfaceName);
610 Optional<Ports> optPorts = NatUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, portsId);
611 IpMapping ipMapping = new IpMappingBuilder().setKey(new IpMappingKey(internalIp)).setInternalIp(internalIp)
612 .setExternalIp(externalIp).setLabel(label).build();
613 if(optPorts.isPresent()) {
614 LOG.debug("Ports {} entry already present. Updating ipmapping for internal ip {}", interfaceName, internalIp);
615 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, portsId.child(IpMapping.class, new IpMappingKey(internalIp)), ipMapping);
617 LOG.debug("Adding Ports entry {} along with ipmapping {}", interfaceName, internalIp);
618 List<IpMapping> ipMappings = new ArrayList<>();
619 ipMappings.add(ipMapping);
620 Ports ports = new PortsBuilder().setKey(new PortsKey(interfaceName)).setPortName(interfaceName).setIpMapping(ipMappings).build();
621 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, portsId, ports);
625 void removeOperationalDS(String routerId, String interfaceName, String internalIp, String externalIp) {
626 LOG.info("Remove operational DS for floating ip config: {}", internalIp);
627 InstanceIdentifier<IpMapping> ipMappingId = NatUtil.getIpMappingIdentifier(routerId, interfaceName, internalIp);
628 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, ipMappingId);
631 private FlowEntity buildPreDNATDeleteFlowEntity(BigInteger dpId, String internalIp, String externalIp, long routerId) {
633 LOG.info("Bulding Delete DNAT Flow entity for ip {} ", externalIp);
635 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.PDNAT_TABLE, routerId, externalIp);
637 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.PDNAT_TABLE, flowRef,
638 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
639 NwConstants.COOKIE_DNAT_TABLE, null, null);
646 private FlowEntity buildDNATDeleteFlowEntity(BigInteger dpId, String internalIp, String externalIp, long routerId) {
648 LOG.info("Bulding Delete DNAT Flow entity for ip {} ", externalIp);
650 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.DNAT_TABLE, routerId, externalIp);
652 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.DNAT_TABLE, flowRef,
653 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
654 NwConstants.COOKIE_DNAT_TABLE, null, null);
660 private FlowEntity buildPreSNATDeleteFlowEntity(BigInteger dpId, String internalIp, long routerId, String externalIp) {
662 LOG.info("Building Delete PSNAT Flow entity for ip {} ", internalIp);
664 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.PSNAT_TABLE, routerId, internalIp);
666 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.PSNAT_TABLE, flowRef,
667 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
668 NwConstants.COOKIE_DNAT_TABLE, null, null);
673 private FlowEntity buildSNATDeleteFlowEntity(BigInteger dpId, String internalIp, long routerId, String externalIp) {
675 LOG.info("Building Delete SNAT Flow entity for ip {} ", internalIp);
677 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.SNAT_TABLE, routerId, internalIp);
679 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.SNAT_TABLE, flowRef,
680 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
681 NwConstants.COOKIE_DNAT_TABLE, null, null);