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 com.google.common.base.Optional;
11 import org.opendaylight.bgpmanager.api.IBgpManager;
12 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
13 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
14 import org.opendaylight.vpnservice.mdsalutil.*;
15 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
16 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fib.rpc.rev160121.FibRpcService;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeGre;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeVxlan;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEgressActionsForInterfaceInputBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEgressActionsForInterfaceOutput;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetTunnelInterfaceNameInputBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetTunnelInterfaceNameOutput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.ItmRpcService;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.*;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.ext.routers.Routers;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.ext.routers.RoutersKey;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.map.IpMapping;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.map.IpMappingKey;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.port.map.IpPortMapping;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.ip.port.map.IpPortExternal;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.napt.switches.RouterToNaptSwitch;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.napt.switches.RouterToNaptSwitchBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.vpn.rpc.rev160201.VpnRpcService;
53 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
54 import org.opendaylight.yangtools.yang.common.RpcResult;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
58 import java.math.BigInteger;
59 import java.util.ArrayList;
60 import java.util.List;
61 import java.util.Objects;
62 import java.util.concurrent.ExecutionException;
63 import java.util.concurrent.Future;
65 public class NaptSwitchHA {
66 private static final Logger LOG = LoggerFactory.getLogger(NaptSwitchHA.class);
67 private final DataBroker dataBroker;
68 private IMdsalApiManager mdsalManager;
69 private ItmRpcService itmManager;
70 private OdlInterfaceRpcService interfaceManager;
71 private IdManagerService idManager;
72 private NAPTSwitchSelector naptSwitchSelector;
73 private ExternalRoutersListener externalRouterListener;
74 private IBgpManager bgpManager;
75 private VpnRpcService vpnService;
76 private FibRpcService fibService;
78 public NaptSwitchHA(DataBroker broker,NAPTSwitchSelector selector){
80 naptSwitchSelector = selector;
83 public void setItmManager(ItmRpcService itmManager) {
84 this.itmManager = itmManager;
87 public void setMdsalManager(IMdsalApiManager mdsalManager) {
88 this.mdsalManager = mdsalManager;
91 public void setInterfaceManager(OdlInterfaceRpcService interfaceManager) {
92 this.interfaceManager = interfaceManager;
95 public void setIdManager(IdManagerService idManager) {
96 this.idManager = idManager;
99 void setExternalRoutersListener(ExternalRoutersListener externalRoutersListener) {
100 this.externalRouterListener = externalRoutersListener;
103 public void setBgpManager(IBgpManager bgpManager) {
104 this.bgpManager = bgpManager;
107 public void setVpnService(VpnRpcService vpnService) {
108 this.vpnService = vpnService;
111 public void setFibService(FibRpcService fibService) {
112 this.fibService = fibService;
115 /* This method checks the switch that gone down is a NaptSwitch for a router.
116 If it is a NaptSwitch
117 1) selects new NAPT switch
118 2) installs nat flows in new NAPT switch
119 table 21(FIB)->26(PSNAT)->group(resubmit/napttunnel)->36(Terminating)->46(outbound)->47(resubmit)->21
120 3) modify the group and miss entry flow in other vSwitches pointing to newNaptSwitch
121 4) Remove nat flows in oldNaptSwitch
123 /*public void handleNaptSwitchDown(BigInteger dpnId){
125 LOG.debug("handleNaptSwitchDown method is called with dpnId {}",dpnId);
126 BigInteger naptSwitch;
128 NaptSwitches naptSwitches = NatUtil.getNaptSwitch(dataBroker);
129 if (naptSwitches == null || naptSwitches.getRouterToNaptSwitch() == null || naptSwitches.getRouterToNaptSwitch().isEmpty()) {
130 LOG.debug("NaptSwitchDown: NaptSwitch is not allocated for none of the routers");
133 for (RouterToNaptSwitch routerToNaptSwitch : naptSwitches.getRouterToNaptSwitch()) {
134 String routerName = routerToNaptSwitch.getRouterName();
135 naptSwitch = routerToNaptSwitch.getPrimarySwitchId();
136 boolean naptStatus = isNaptSwitchDown(routerName,dpnId,naptSwitch);
138 LOG.debug("NaptSwitchDown: Switch with DpnId {} is not naptSwitch for router {}",
141 removeSnatFlowsInOldNaptSwitch(routerName,naptSwitch);
145 } catch (Exception ex) {
146 LOG.error("Exception in handleNaptSwitchDown method {}",ex);
150 protected void removeSnatFlowsInOldNaptSwitch(String routerName, BigInteger naptSwitch) {
151 //remove SNAT flows in old NAPT SWITCH
152 Long routerId = NatUtil.getVpnId(dataBroker, routerName);
153 if (routerId == NatConstants.INVALID_ID) {
154 LOG.error("Invalid routerId returned for routerName {}",routerName);
158 //Remove the Terminating Service table entry which forwards the packet to Outbound NAPT Table
159 String tsFlowRef = externalRouterListener.getFlowRefTs(naptSwitch, NatConstants.TERMINATING_SERVICE_TABLE, routerId);
160 FlowEntity tsNatFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NatConstants.TERMINATING_SERVICE_TABLE, tsFlowRef);
162 LOG.info("Remove the flow in table {} for the old napt switch with the DPN ID {} and router ID {}"
163 ,NatConstants.TERMINATING_SERVICE_TABLE, naptSwitch, routerId);
164 mdsalManager.removeFlow(tsNatFlowEntity);
166 //Remove the Outbound flow entry which forwards the packet to Outbound NAPT Table
167 String outboundNatFlowRef = externalRouterListener.getFlowRefOutbound(naptSwitch, NatConstants.OUTBOUND_NAPT_TABLE, routerId);
168 FlowEntity outboundNatFlowEntity = NatUtil.buildFlowEntity(naptSwitch,
169 NatConstants.OUTBOUND_NAPT_TABLE, outboundNatFlowRef);
170 LOG.info("Remove the flow in table {} for the old napt switch with the DPN ID {} and router ID {}"
171 ,NatConstants.OUTBOUND_NAPT_TABLE, naptSwitch, routerId);
172 mdsalManager.removeFlow(outboundNatFlowEntity);
174 //Remove the NAPT_PFIB_TABLE(47) flow entry forwards the packet to Fib Table for inbound traffic matching on the router ID.
175 String naptPFibflowRef = externalRouterListener.getFlowRefTs(naptSwitch, NatConstants.NAPT_PFIB_TABLE, routerId);
176 FlowEntity naptPFibFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NatConstants.NAPT_PFIB_TABLE,naptPFibflowRef);
177 LOG.info("Remove the flow in table {} for the old napt switch with the DPN ID {} and router ID {}",
178 NatConstants.NAPT_PFIB_TABLE, naptSwitch, routerId);
179 mdsalManager.removeFlow(naptPFibFlowEntity);
181 //Remove the NAPT_PFIB_TABLE(47) flow entry forwards the packet to Fib Table for outbound traffic matching on the vpn ID.
182 Long vpnId = getVpnIdForRouter(routerId);
183 if (vpnId != NatConstants.INVALID_ID) {
184 String naptFibflowRef = externalRouterListener.getFlowRefTs(naptSwitch, NatConstants.NAPT_PFIB_TABLE, vpnId);
185 FlowEntity naptFibFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NatConstants.NAPT_PFIB_TABLE,naptFibflowRef);
186 LOG.info("Remove the flow in table {} for the old napt switch with the DPN ID {} and vpnId {}",
187 NatConstants.NAPT_PFIB_TABLE, naptSwitch, vpnId);
188 mdsalManager.removeFlow(naptFibFlowEntity);
190 LOG.error("Invalid vpnId retrieved for routerId {}",routerId);
194 //Remove Fib entries and 36-> 44
195 Uuid networkId = NatUtil.getNetworkIdFromRouterId(dataBroker, routerId);
196 if (networkId != null) {
197 List<String> externalIps = NatUtil.getExternalIpsForRouter(dataBroker, routerId);
198 if (externalIps != null) {
199 externalRouterListener.clrRtsFromBgpAndDelFibTs(naptSwitch, routerId, networkId, externalIps, null);
200 LOG.debug("Successfully removed fib entries in old naptswitch {} for router {} with networkId {} and externalIps {}",
201 naptSwitch,routerId,networkId,externalIps);
203 LOG.debug("ExternalIps not found for router {} with networkId {}", routerName, networkId);
206 LOG.debug("network not associated to router {}", routerId);
209 //For the router ID get the internal IP , internal port and the corresponding external IP and external Port.
210 IpPortMapping ipPortMapping = NatUtil.getIportMapping(dataBroker, routerId);
211 if (ipPortMapping == null || ipPortMapping.getIntextIpProtocolType() == null || ipPortMapping.getIntextIpProtocolType().isEmpty()) {
212 LOG.debug("No Internal Ip Port mapping associated to router {}, no flows need to be removed in" +
213 "oldNaptSwitch {}", routerId, naptSwitch);
216 BigInteger cookieSnatFlow = NatUtil.getCookieNaptFlow(routerId);
217 List<IntextIpProtocolType> intextIpProtocolTypes = ipPortMapping.getIntextIpProtocolType();
218 for(IntextIpProtocolType intextIpProtocolType : intextIpProtocolTypes) {
219 if (intextIpProtocolType.getIpPortMap() == null || intextIpProtocolType.getIpPortMap().isEmpty()) {
220 LOG.debug("No {} session associated to router {},no flows need to be removed in oldNaptSwitch {}",
221 intextIpProtocolType.getProtocol(),routerId,naptSwitch);
224 List<IpPortMap> ipPortMaps = intextIpProtocolType.getIpPortMap();
225 for(IpPortMap ipPortMap : ipPortMaps) {
226 String ipPortInternal = ipPortMap.getIpPortInternal();
227 String[] ipPortParts = ipPortInternal.split(":");
228 if(ipPortParts.length != 2) {
229 LOG.error("Unable to retrieve the Internal IP and port");
232 String internalIp = ipPortParts[0];
233 String internalPort = ipPortParts[1];
235 //Build and remove flow in outbound NAPT table
236 String switchFlowRef = NatUtil.getNaptFlowRef(naptSwitch, NatConstants.OUTBOUND_NAPT_TABLE, String.valueOf(routerId),
237 internalIp, Integer.valueOf(internalPort));
238 FlowEntity outboundNaptFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NatConstants.OUTBOUND_NAPT_TABLE,
239 cookieSnatFlow, switchFlowRef);
241 LOG.info("Remove the flow in table {} for old napt switch with the DPN ID {} and router ID {}",
242 NatConstants.OUTBOUND_NAPT_TABLE,naptSwitch, routerId);
243 mdsalManager.removeFlow(outboundNaptFlowEntity);
245 IpPortExternal ipPortExternal = ipPortMap.getIpPortExternal();
246 if (ipPortExternal == null) {
247 LOG.debug("External Ipport mapping not found for internalIp {} with port {} for router", internalIp,
248 internalPort, routerId);
251 String externalIp = ipPortExternal.getIpAddress();
252 int externalPort = ipPortExternal.getPortNum();
254 //Build and remove flow in inbound NAPT table
255 switchFlowRef = NatUtil.getNaptFlowRef(naptSwitch, NatConstants.INBOUND_NAPT_TABLE, String.valueOf(routerId),
256 externalIp, externalPort);
257 FlowEntity inboundNaptFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NatConstants.INBOUND_NAPT_TABLE,
258 cookieSnatFlow, switchFlowRef);
260 LOG.info("Remove the flow in table {} for old napt switch with the DPN ID {} and router ID {}",
261 NatConstants.INBOUND_NAPT_TABLE,naptSwitch, routerId);
262 mdsalManager.removeFlow(inboundNaptFlowEntity);
268 /*public boolean isNaptSwitchDown(String routerName, BigInteger dpnId , BigInteger naptSwitch) {
269 if (!naptSwitch.equals(dpnId)) {
270 LOG.debug("DpnId {} is not a naptSwitch {} for Router {}",dpnId, naptSwitch, routerName);
273 LOG.debug("NaptSwitch {} is down for Router {}", naptSwitch, routerName);
274 //elect a new NaptSwitch
275 naptSwitch = naptSwitchSelector.selectNewNAPTSwitch(routerName);
276 if (naptSwitch.equals(BigInteger.ZERO)) {
277 LOG.info("No napt switch is elected since all the switches for router {} are down",routerName);
278 boolean naptUpdatedStatus = updateNaptSwitch(routerName,naptSwitch);
279 if(!naptUpdatedStatus) {
280 LOG.debug("Failed to update naptSwitch {} for router {} in ds", naptSwitch,routerName);
284 //checking elected switch health status
285 if (!getSwitchStatus(naptSwitch)) {
286 LOG.error("Newly elected Napt switch {} for router {} is down", naptSwitch, routerName);
289 LOG.debug("New NaptSwitch {} is up for Router {} and can proceed for flow installation",naptSwitch, routerName);
290 Long routerId = NatUtil.getVpnId(dataBroker, routerName);
291 if (routerId == NatConstants.INVALID_ID) {
292 LOG.error("Invalid routerId returned for routerName {}", routerName);
295 //update napt model for new napt switch
296 boolean naptUpdated = updateNaptSwitch(routerName, naptSwitch);
298 //update group of naptswitch point to table36/ordinary switch point to naptswitchtunnelport
299 updateNaptSwitchBucketStatus(routerName, naptSwitch);
301 LOG.error("Failed to update naptSwitch model for newNaptSwitch {} for router {}",naptSwitch, routerName);
304 installSnatFlows(routerName,routerId,naptSwitch);
306 boolean flowInstalledStatus = handleNatFlowsInNewNaptSwitch(routerId, dpnId, naptSwitch);
307 if (flowInstalledStatus) {
308 LOG.debug("Installed all active session flows in newNaptSwitch {} for routerName {}", naptSwitch, routerName);
310 LOG.error("Failed to install flows in newNaptSwitch {} for routerId {}", naptSwitch, routerId);
315 public boolean isNaptSwitchDown(String routerName, BigInteger dpnId , BigInteger naptSwitch,Long routerVpnId) {
316 if (!naptSwitch.equals(dpnId)) {
317 LOG.debug("DpnId {} is not a naptSwitch {} for Router {}",dpnId, naptSwitch, routerName);
320 LOG.debug("NaptSwitch {} is down for Router {}", naptSwitch, routerName);
321 //elect a new NaptSwitch
322 naptSwitch = naptSwitchSelector.selectNewNAPTSwitch(routerName);
323 if (naptSwitch.equals(BigInteger.ZERO)) {
324 LOG.info("No napt switch is elected since all the switches for router {} are down",routerName);
325 boolean naptUpdatedStatus = updateNaptSwitch(routerName,naptSwitch);
326 if(!naptUpdatedStatus) {
327 LOG.debug("Failed to update naptSwitch {} for router {} in ds", naptSwitch,routerName);
331 //checking elected switch health status
332 if (!getSwitchStatus(naptSwitch)) {
333 LOG.error("Newly elected Napt switch {} for router {} is down", naptSwitch, routerName);
336 LOG.debug("New NaptSwitch {} is up for Router {} and can proceed for flow installation",naptSwitch, routerName);
337 Long routerId = NatUtil.getVpnId(dataBroker, routerName);
338 if (routerId == NatConstants.INVALID_ID) {
339 LOG.error("Invalid routerId returned for routerName {}", routerName);
342 //update napt model for new napt switch
343 boolean naptUpdated = updateNaptSwitch(routerName, naptSwitch);
345 //update group of naptswitch point to table36/ordinary switch point to naptswitchtunnelport
346 updateNaptSwitchBucketStatus(routerName, naptSwitch);
348 LOG.error("Failed to update naptSwitch model for newNaptSwitch {} for router {}",naptSwitch, routerName);
351 installSnatFlows(routerName,routerId,naptSwitch,routerVpnId);
353 boolean flowInstalledStatus = handleNatFlowsInNewNaptSwitch(routerId, dpnId, naptSwitch,routerVpnId);
354 if (flowInstalledStatus) {
355 LOG.debug("Installed all active session flows in newNaptSwitch {} for routerName {}", naptSwitch, routerName);
357 LOG.error("Failed to install flows in newNaptSwitch {} for routerId {}", naptSwitch, routerId);
362 private String getExtNetworkVpnName(long routerId) {
363 Uuid networkId = NatUtil.getNetworkIdFromRouterId(dataBroker, routerId);
364 if(networkId == null) {
365 LOG.error("networkId is null for the router ID {}", routerId);
367 final String vpnName = NatUtil.getAssociatedVPN(dataBroker, networkId, LOG);
368 if (vpnName != null) {
369 LOG.debug("retrieved vpn name {} associated with ext nw {} in router {}",
370 vpnName,networkId,routerId);
373 LOG.error("No VPN associated with ext nw {} belonging to routerId {}",
374 networkId, routerId);
380 public void updateNaptSwitchBucketStatus(String routerName, BigInteger naptSwitch) {
381 LOG.debug("updateNaptSwitchBucketStatus method is called");
383 List<BigInteger> dpnList = naptSwitchSelector.getDpnsForVpn(routerName);
384 //List<BigInteger> dpnList = getDpnListForRouter(routerName);
385 for (BigInteger dpn : dpnList) {
386 if (dpn.equals(naptSwitch)) {
387 LOG.debug("Updating SNAT_TABLE missentry for DpnId {} which is naptSwitch for router {}",dpn,routerName);
388 List<BucketInfo> bucketInfoList = handleGroupInPrimarySwitch();
389 modifySnatGroupEntry(naptSwitch, bucketInfoList, routerName);
391 LOG.debug("Updating SNAT_TABLE missentry for DpnId {} which is not naptSwitch for router {}",dpn,routerName);
392 List<BucketInfo> bucketInfoList = handleGroupInNeighborSwitches(dpn, routerName, naptSwitch);
393 if (bucketInfoList == null) {
394 LOG.debug("Failed to populate bucketInfo for orinaryswitch {} whose naptSwitch {} for router {} ",
395 dpn,naptSwitch,routerName);
398 modifySnatGroupEntry(naptSwitch, bucketInfoList, routerName);
403 /*private boolean handleNatFlowsInNewNaptSwitch(Long routerId,BigInteger oldNaptSwitch, BigInteger newNaptSwitch) {
405 LOG.debug("Proceeding to install flows in newNaptSwitch {} for routerId {}", newNaptSwitch,routerId);
406 IpPortMapping ipPortMapping = NatUtil.getIportMapping(dataBroker,routerId);
407 if (ipPortMapping == null || ipPortMapping.getIntextIpProtocolType() == null || ipPortMapping.getIntextIpProtocolType().isEmpty()) {
408 LOG.debug("No Internal Ip Port mapping associated to router {}, no flows need to be installed in" +
409 "newNaptSwitch {}", routerId, newNaptSwitch);
413 Long vpnId = getVpnIdForRouter(routerId);
414 if (vpnId == NatConstants.INVALID_ID) {
415 LOG.error("Invalid vpnId for routerId {}",routerId);
418 Long bgpVpnId = NatConstants.INVALID_ID;
419 for (IntextIpProtocolType protocolType : ipPortMapping.getIntextIpProtocolType()) {
420 if (protocolType.getIpPortMap() == null || protocolType.getIpPortMap().isEmpty()) {
421 LOG.debug("No {} session associated to router {}", protocolType.getProtocol(), routerId);
424 for (IpPortMap intIpPortMap : protocolType.getIpPortMap()) {
425 String internalIpAddress = intIpPortMap.getIpPortInternal().split(":")[0];
426 String intportnum = intIpPortMap.getIpPortInternal().split(":")[1];
428 //Get the external IP address and the port from the model
429 NAPTEntryEvent.Protocol proto = protocolType.getProtocol().toString().equals(ProtocolTypes.TCP.toString())
430 ? NAPTEntryEvent.Protocol.TCP : NAPTEntryEvent.Protocol.UDP;
431 IpPortExternal ipPortExternal = NatUtil.getExternalIpPortMap(dataBroker, routerId,
432 internalIpAddress, intportnum, proto);
433 if (ipPortExternal == null) {
434 LOG.debug("External Ipport mapping is not found for internalIp {} with port {}", internalIpAddress, intportnum);
437 String externalIpAddress = ipPortExternal.getIpAddress();
438 Integer extportNumber = ipPortExternal.getPortNum();
439 LOG.debug("ExternalIPport {}:{} mapping for internal ipport {}:{}",externalIpAddress,extportNumber,
440 internalIpAddress,intportnum);
442 SessionAddress sourceAddress = new SessionAddress(internalIpAddress,Integer.valueOf(intportnum));
443 SessionAddress externalAddress = new SessionAddress(externalIpAddress,extportNumber);
445 //checking naptSwitch status before installing flows
446 if(getSwitchStatus(newNaptSwitch)) {
447 //Install the flow in newNaptSwitch Outbound NAPT table.
449 NaptEventHandler.buildAndInstallNatFlows(newNaptSwitch, NatConstants.OUTBOUND_NAPT_TABLE,
450 vpnId, routerId, bgpVpnId ,sourceAddress, externalAddress, proto);
451 } catch (Exception ex) {
452 LOG.error("Failed to add flow in OUTBOUND_NAPT_TABLE for routerid {} dpnId {} ipport {}:{} proto {}" +
453 "extIpport {}:{}", routerId, newNaptSwitch, internalIpAddress
454 , intportnum, proto, externalAddress, extportNumber);
457 LOG.debug("Succesfully installed a flow in SecondarySwitch {} Outbound NAPT table for router {} " +
458 "ipport {}:{} proto {} extIpport {}:{}", newNaptSwitch,routerId, internalIpAddress
459 , intportnum, proto, externalAddress, extportNumber);
460 //Install the flow in newNaptSwitch Inbound NAPT table.
462 NaptEventHandler.buildAndInstallNatFlows(newNaptSwitch, NatConstants.INBOUND_NAPT_TABLE,
463 vpnId, routerId, bgpVpnId,externalAddress, sourceAddress, proto);
464 } catch (Exception ex) {
465 LOG.error("Failed to add flow in INBOUND_NAPT_TABLE for routerid {} dpnId {} extIpport{}:{} proto {} ipport {}:{}",
466 routerId, newNaptSwitch, externalAddress, extportNumber,
467 proto, internalIpAddress, intportnum);
470 LOG.debug("Succesfully installed a flow in SecondarySwitch {} Inbound NAPT table for router {} " +
471 "ipport {}:{} proto {} extIpport {}:{}", newNaptSwitch,routerId, internalIpAddress
472 , intportnum, proto, externalAddress, extportNumber);
475 LOG.error("NewNaptSwitch {} gone down while installing flows from oldNaptswitch {}",
476 newNaptSwitch,oldNaptSwitch);
484 private boolean handleNatFlowsInNewNaptSwitch(Long routerId,BigInteger oldNaptSwitch, BigInteger newNaptSwitch,Long routerVpnId) {
486 LOG.debug("Proceeding to install flows in newNaptSwitch {} for routerId {}", newNaptSwitch,routerId);
487 IpPortMapping ipPortMapping = NatUtil.getIportMapping(dataBroker,routerId);
488 if (ipPortMapping == null || ipPortMapping.getIntextIpProtocolType() == null || ipPortMapping.getIntextIpProtocolType().isEmpty()) {
489 LOG.debug("No Internal Ip Port mapping associated to router {}, no flows need to be installed in" +
490 "newNaptSwitch {}", routerId, newNaptSwitch);
494 Long vpnId = getVpnIdForRouter(routerId);
495 if (vpnId == NatConstants.INVALID_ID) {
496 LOG.error("Invalid vpnId for routerId {}",routerId);
500 if(routerId.equals(routerVpnId)) {
501 bgpVpnId = NatConstants.INVALID_ID;
503 bgpVpnId = routerVpnId;
505 LOG.debug("retrieved bgpVpnId {} for router {}",bgpVpnId,routerId);
506 for (IntextIpProtocolType protocolType : ipPortMapping.getIntextIpProtocolType()) {
507 if (protocolType.getIpPortMap() == null || protocolType.getIpPortMap().isEmpty()) {
508 LOG.debug("No {} session associated to router {}", protocolType.getProtocol(), routerId);
511 for (IpPortMap intIpPortMap : protocolType.getIpPortMap()) {
512 String internalIpAddress = intIpPortMap.getIpPortInternal().split(":")[0];
513 String intportnum = intIpPortMap.getIpPortInternal().split(":")[1];
515 //Get the external IP address and the port from the model
516 NAPTEntryEvent.Protocol proto = protocolType.getProtocol().toString().equals(ProtocolTypes.TCP.toString())
517 ? NAPTEntryEvent.Protocol.TCP : NAPTEntryEvent.Protocol.UDP;
518 IpPortExternal ipPortExternal = NatUtil.getExternalIpPortMap(dataBroker, routerId,
519 internalIpAddress, intportnum, proto);
520 if (ipPortExternal == null) {
521 LOG.debug("External Ipport mapping is not found for internalIp {} with port {}", internalIpAddress, intportnum);
524 String externalIpAddress = ipPortExternal.getIpAddress();
525 Integer extportNumber = ipPortExternal.getPortNum();
526 LOG.debug("ExternalIPport {}:{} mapping for internal ipport {}:{}",externalIpAddress,extportNumber,
527 internalIpAddress,intportnum);
529 SessionAddress sourceAddress = new SessionAddress(internalIpAddress,Integer.valueOf(intportnum));
530 SessionAddress externalAddress = new SessionAddress(externalIpAddress,extportNumber);
532 //checking naptSwitch status before installing flows
533 if(getSwitchStatus(newNaptSwitch)) {
534 //Install the flow in newNaptSwitch Outbound NAPT table.
536 NaptEventHandler.buildAndInstallNatFlows(newNaptSwitch, NatConstants.OUTBOUND_NAPT_TABLE,
537 vpnId, routerId, bgpVpnId, sourceAddress, externalAddress, proto);
538 } catch (Exception ex) {
539 LOG.error("Failed to add flow in OUTBOUND_NAPT_TABLE for routerid {} dpnId {} ipport {}:{} proto {}" +
540 "extIpport {}:{} BgpVpnId {} - {}", routerId, newNaptSwitch, internalIpAddress
541 , intportnum, proto, externalAddress, extportNumber,bgpVpnId,ex);
544 LOG.debug("Successfully installed a flow in SecondarySwitch {} Outbound NAPT table for router {} " +
545 "ipport {}:{} proto {} extIpport {}:{} BgpVpnId {}", newNaptSwitch,routerId, internalIpAddress
546 , intportnum, proto, externalAddress, extportNumber,bgpVpnId);
547 //Install the flow in newNaptSwitch Inbound NAPT table.
549 NaptEventHandler.buildAndInstallNatFlows(newNaptSwitch, NatConstants.INBOUND_NAPT_TABLE,
550 vpnId, routerId, bgpVpnId, externalAddress, sourceAddress, proto);
551 } catch (Exception ex) {
552 LOG.error("Failed to add flow in INBOUND_NAPT_TABLE for routerid {} dpnId {} extIpport{}:{} proto {} " +
553 "ipport {}:{} BgpVpnId {}", routerId, newNaptSwitch, externalAddress, extportNumber, proto,
554 internalIpAddress, intportnum,bgpVpnId);
557 LOG.debug("Successfully installed a flow in SecondarySwitch {} Inbound NAPT table for router {} " +
558 "ipport {}:{} proto {} extIpport {}:{} BgpVpnId {}", newNaptSwitch,routerId, internalIpAddress
559 , intportnum, proto, externalAddress, extportNumber,bgpVpnId);
562 LOG.error("NewNaptSwitch {} gone down while installing flows from oldNaptswitch {}",
563 newNaptSwitch,oldNaptSwitch);
571 private Long getVpnIdForRouter(Long routerId) {
574 Uuid networkId = NatUtil.getNetworkIdFromRouterId(dataBroker, routerId);
575 if (networkId == null) {
576 LOG.debug("network is not associated to router {}", routerId);
578 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
579 if (vpnUuid == null) {
580 LOG.debug("vpn is not associated for network {} in router {}", networkId, routerId);
582 Long vpnId = NatUtil.getVpnId(dataBroker, vpnUuid.getValue());
584 LOG.debug("retrieved vpnId {} for router {}",vpnId,routerId);
587 LOG.debug("retrieved invalid vpn Id");
591 } catch (Exception ex){
592 LOG.debug("Exception while retrieving vpnId for router {} - {}", routerId, ex);
594 return NatConstants.INVALID_ID;
598 private List<BigInteger> getDpnListForRouter(String routerName) {
599 long bgpVpnId = NatUtil.getBgpVpnId(dataBroker, routerName);
600 if (bgpVpnId != NatConstants.INVALID_ID) {
601 return NatUtil.getDpnsForRouter(dataBroker, routerName);
603 List<BigInteger> dpnList = new ArrayList<BigInteger>();
604 List<VpnToDpnList> vpnDpnList = NatUtil.getVpnToDpnList(dataBroker, routerName);
605 if (vpnDpnList == null || vpnDpnList.isEmpty()) {
606 LOG.debug("NAT Service : Unable to get the switches for the router {} from the VPNInstanceOpData", routerName);
607 dpnList = NatUtil.getDpnsForRouter(dataBroker, routerName);
608 if(dpnList == null || dpnList.isEmpty()){
609 LOG.debug("NAT Service : No switches are part of router {}", routerName);
610 LOG.error("NAT Service : NAPT SWITCH SELECTION STOPPED DUE TO NO DPNS SCENARIO FOR ROUTER {}", routerName);
613 for (VpnToDpnList vpnToDpn : vpnDpnList) {
614 dpnList.add(vpnToDpn.getDpnId());
621 public boolean getSwitchStatus(BigInteger switchId){
622 NodeId nodeId = new NodeId("openflow:" + switchId);
623 LOG.debug("Querying switch with dpnId {} is up/down", nodeId);
624 InstanceIdentifier<Node> nodeInstanceId = InstanceIdentifier.builder(Nodes.class)
625 .child(Node.class, new NodeKey(nodeId)).build();
626 Optional<Node> nodeOptional = NatUtil.read(dataBroker,LogicalDatastoreType.OPERATIONAL,nodeInstanceId);
627 if (nodeOptional.isPresent()) {
628 LOG.debug("Switch {} is up", nodeId);
631 LOG.debug("Switch {} is down", nodeId);
635 public List<BucketInfo> handleGroupInPrimarySwitch() {
636 List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
637 List<ActionInfo> listActionInfoPrimary = new ArrayList<ActionInfo>();
638 listActionInfoPrimary.add(new ActionInfo(ActionType.nx_resubmit,
639 new String[]{String.valueOf(NatConstants.TERMINATING_SERVICE_TABLE)}));
640 BucketInfo bucketPrimary = new BucketInfo(listActionInfoPrimary);
641 listBucketInfo.add(bucketPrimary);
642 return listBucketInfo;
645 public List<BucketInfo> handleGroupInNeighborSwitches(BigInteger dpnId, String routerName, BigInteger naptSwitch) {
646 List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
647 String ifNamePrimary;
648 Long routerId = NatUtil.getVpnId(dataBroker, routerName);
649 if (routerId == NatConstants.INVALID_ID) {
650 LOG.error("Invalid routerId returned for routerName {}",routerName);
651 return listBucketInfo;
653 ifNamePrimary = getTunnelInterfaceName(dpnId, naptSwitch);
654 if (ifNamePrimary != null) {
655 LOG.debug("TunnelInterface {} between ordinary switch {} and naptSwitch {}",ifNamePrimary,dpnId,naptSwitch);
656 List<ActionInfo> listActionInfoPrimary = getEgressActionsForInterface(ifNamePrimary, routerId);
657 BucketInfo bucketPrimary = new BucketInfo(listActionInfoPrimary);
658 listBucketInfo.add(bucketPrimary);
660 LOG.debug("No TunnelInterface between ordinary switch {} and naptSwitch {}",dpnId,naptSwitch);
662 return listBucketInfo;
665 protected void installSnatGroupEntry(BigInteger dpnId, List<BucketInfo> bucketInfo, String routerName) {
666 GroupEntity groupEntity = null;
668 long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(routerName), idManager);
669 LOG.debug("install SnatMissEntry for groupId {} for dpnId {} for router {}", groupId, dpnId,routerName);
670 groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName,
671 GroupTypes.GroupAll, bucketInfo);
672 mdsalManager.installGroup(groupEntity);
673 LOG.debug("installed the SNAT to NAPT GroupEntity:{}", groupEntity);
674 } catch (Exception ex) {
675 LOG.error("Failed to install group for groupEntity {} : {}",groupEntity,ex);
679 private void modifySnatGroupEntry(BigInteger dpnId, List<BucketInfo> bucketInfo, String routerName) {
680 installSnatGroupEntry(dpnId,bucketInfo,routerName);
681 LOG.debug("modified SnatMissEntry for dpnId {} of router {}",dpnId,routerName);
684 protected String getTunnelInterfaceName(BigInteger srcDpId, BigInteger dstDpId) {
685 Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
686 RpcResult<GetTunnelInterfaceNameOutput> rpcResult;
689 Future<RpcResult<GetTunnelInterfaceNameOutput>> result = itmManager.getTunnelInterfaceName(
690 new GetTunnelInterfaceNameInputBuilder().setSourceDpid(srcDpId).setDestinationDpid(dstDpId).
691 // .setTunnelType(tunType).
693 rpcResult = result.get();
694 if(!rpcResult.isSuccessful()) {
695 tunType = TunnelTypeGre.class;
696 result = itmManager.getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder()
697 .setSourceDpid(srcDpId)
698 .setDestinationDpid(dstDpId)
699 // .setTunnelType(tunType)
701 rpcResult = result.get();
702 if(!rpcResult.isSuccessful()) {
703 LOG.warn("RPC Call to getTunnelInterfaceId returned with Errors {}", rpcResult.getErrors());
705 return rpcResult.getResult().getInterfaceName();
707 LOG.warn("RPC Call to getTunnelInterfaceId returned with Errors {}", rpcResult.getErrors());
709 return rpcResult.getResult().getInterfaceName();
711 } catch (InterruptedException | ExecutionException e) {
712 LOG.warn("Exception when getting tunnel interface Id for tunnel between {} and {} : {}",
713 srcDpId, dstDpId, e);
719 protected List<ActionInfo> getEgressActionsForInterface(String ifName, long routerId) {
720 LOG.debug("getEgressActionsForInterface called for interface {}", ifName);
721 List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
723 Future<RpcResult<GetEgressActionsForInterfaceOutput>> result =
724 interfaceManager.getEgressActionsForInterface(
725 new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName).setTunnelKey(routerId).build());
726 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
727 if(!rpcResult.isSuccessful()) {
728 LOG.warn("RPC Call to Get egress actions for interface {} returned with Errors {}"
729 , ifName, rpcResult.getErrors());
731 List<Action> actions =
732 rpcResult.getResult().getAction();
733 for (Action action : actions) {
734 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionClass = action.getAction();
735 if (actionClass instanceof OutputActionCase) {
736 listActionInfo.add(new ActionInfo(ActionType.output,
737 new String[] {((OutputActionCase)actionClass).getOutputAction()
738 .getOutputNodeConnector().getValue()}));
739 } else if (actionClass instanceof PushVlanActionCase) {
740 listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] {}));
741 } else if (actionClass instanceof SetFieldCase) {
742 if (((SetFieldCase)actionClass).getSetField().getVlanMatch() != null) {
743 int vlanVid = ((SetFieldCase)actionClass).getSetField().getVlanMatch()
744 .getVlanId().getVlanId().getValue();
745 listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid,
746 new String[] { Long.toString(vlanVid) }));
751 } catch (InterruptedException | ExecutionException e) {
752 LOG.warn("Exception when egress actions for interface {}", ifName, e);
754 return listActionInfo;
757 public boolean updateNaptSwitch(String routerName, BigInteger naptSwitchId) {
758 RouterToNaptSwitch naptSwitch = new RouterToNaptSwitchBuilder().setKey(new RouterToNaptSwitchKey(routerName))
759 .setPrimarySwitchId(naptSwitchId).build();
761 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
762 NatUtil.buildNaptSwitchRouterIdentifier(routerName), naptSwitch);
763 } catch (Exception ex) {
764 LOG.error("Failed to write naptSwitch {} for router {} in ds",
765 naptSwitchId,routerName);
768 LOG.debug("Successfully updated naptSwitch {} for router {} in ds",
769 naptSwitchId,routerName);
773 /*public FlowEntity buildSnatFlowEntity(BigInteger dpId, String routerName, long groupId, int addordel) {
775 FlowEntity flowEntity;
776 long routerId = NatUtil.getVpnId(dataBroker, routerName);
777 if (routerId == NatConstants.INVALID_ID) {
778 LOG.error("Invalid routerId returned for routerName {}",routerName);
781 List<MatchInfo> matches = new ArrayList<MatchInfo>();
782 matches.add(new MatchInfo(MatchFieldType.eth_type,
783 new long[]{ 0x0800L }));
784 matches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
785 BigInteger.valueOf(routerId), MetaDataUtil.METADATA_MASK_VRFID }));
787 String flowRef = getFlowRefSnat(dpId, NatConstants.PSNAT_TABLE, routerName);
789 if (addordel == NatConstants.ADD_FLOW) {
790 List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
791 List<ActionInfo> actionsInfo = new ArrayList<ActionInfo>();
793 ActionInfo actionSetField = new ActionInfo(ActionType.set_field_tunnel_id, new BigInteger[] {
794 BigInteger.valueOf(routerId)}) ;
795 actionsInfo.add(actionSetField);
796 LOG.debug("Setting the tunnel to the list of action infos {}", actionsInfo);
797 actionsInfo.add(new ActionInfo(ActionType.group, new String[] {String.valueOf(groupId)}));
798 instructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfo));
800 flowEntity = MDSALUtil.buildFlowEntity(dpId, NatConstants.PSNAT_TABLE, flowRef,
801 NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef, 0, 0,
802 NatConstants.COOKIE_SNAT_TABLE, matches, instructions);
804 flowEntity = MDSALUtil.buildFlowEntity(dpId, NatConstants.PSNAT_TABLE, flowRef,
805 NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef, 0, 0,
806 NatConstants.COOKIE_SNAT_TABLE, matches, null);
811 public FlowEntity buildSnatFlowEntity(BigInteger dpId, String routerName, long groupId, long routerVpnId, int addordel) {
813 FlowEntity flowEntity;
814 List<MatchInfo> matches = new ArrayList<MatchInfo>();
815 matches.add(new MatchInfo(MatchFieldType.eth_type,
816 new long[]{ 0x0800L }));
817 matches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
818 BigInteger.valueOf(routerVpnId), MetaDataUtil.METADATA_MASK_VRFID }));
820 String flowRef = getFlowRefSnat(dpId, NatConstants.PSNAT_TABLE, routerName);
822 if (addordel == NatConstants.ADD_FLOW) {
823 List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
824 List<ActionInfo> actionsInfo = new ArrayList<ActionInfo>();
826 ActionInfo actionSetField = new ActionInfo(ActionType.set_field_tunnel_id, new BigInteger[] {
827 BigInteger.valueOf(routerVpnId)}) ;
828 actionsInfo.add(actionSetField);
829 LOG.debug("Setting the tunnel to the list of action infos {}", actionsInfo);
830 actionsInfo.add(new ActionInfo(ActionType.group, new String[] {String.valueOf(groupId)}));
831 instructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfo));
833 flowEntity = MDSALUtil.buildFlowEntity(dpId, NatConstants.PSNAT_TABLE, flowRef,
834 NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef, 0, 0,
835 NatConstants.COOKIE_SNAT_TABLE, matches, instructions);
837 flowEntity = MDSALUtil.buildFlowEntity(dpId, NatConstants.PSNAT_TABLE, flowRef,
838 NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef, 0, 0,
839 NatConstants.COOKIE_SNAT_TABLE, matches, null);
844 private String getFlowRefSnat(BigInteger dpnId, short tableId, String routerID) {
845 return new StringBuilder().append(NatConstants.SNAT_FLOWID_PREFIX).append(dpnId).append(NatConstants.FLOWID_SEPARATOR).
846 append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID).toString();
849 /*protected void installSnatFlows(String routerName,Long routerId,BigInteger naptSwitch) {
850 //36 -> 46 ..Install flow forwarding packet to table46 from table36
851 LOG.debug("installTerminatingServiceTblEntry in naptswitch with dpnId {} for routerName {}", naptSwitch, routerName);
852 externalRouterListener.installTerminatingServiceTblEntry(naptSwitch, routerName);
854 //Install default flows punting to controller in table 46(OutBoundNapt table)
855 LOG.debug("installOutboundMissEntry in naptswitch with dpnId {} for routerName {}", naptSwitch, routerName);
856 externalRouterListener.installOutboundMissEntry(routerName, naptSwitch);
858 //Table 47 point to table 21 for inbound traffic
859 LOG.debug("installNaptPfibEntry in naptswitch with dpnId {} for routerId {}", naptSwitch, routerId);
860 externalRouterListener.installNaptPfibEntry(naptSwitch, routerId);
862 String vpnName = getExtNetworkVpnName(routerId);
863 if(vpnName != null) {
864 //Table 47 point to table 21 for outbound traffic
865 long vpnId = NatUtil.getVpnId(dataBroker, vpnName);
867 LOG.debug("installNaptPfibEntry fin naptswitch with dpnId {} for vpnId {}", naptSwitch, vpnId);
868 externalRouterListener.installNaptPfibEntry(naptSwitch, vpnId);
870 LOG.debug("Associated vpnId not found for router {}",routerId);
873 //Install Fib entries for ExternalIps & program 36 -> 44
874 List<String> externalIps = NatUtil.getExternalIpsForRouter(dataBroker,routerId);
875 if (externalIps != null) {
876 for (String externalIp : externalIps) {
877 LOG.debug("advToBgpAndInstallFibAndTsFlows in naptswitch id {} with vpnName {} and externalIp {}",
878 naptSwitch, vpnName, externalIp);
879 externalRouterListener.advToBgpAndInstallFibAndTsFlows(naptSwitch, NatConstants.INBOUND_NAPT_TABLE,
880 vpnName, routerId, externalIp, vpnService, fibService, bgpManager, dataBroker, LOG);
881 LOG.debug("Successfully added fib entries in naptswitch {} for router {} with external IP {}", naptSwitch,
882 routerId, externalIp);
885 LOG.debug("External Ip not found for routerId {}",routerId);
888 LOG.debug("Associated vpnName not found for router {}",routerId);
892 protected void installSnatFlows(String routerName,Long routerId,BigInteger naptSwitch,Long routerVpnId) {
894 if(routerId.equals(routerVpnId)) {
895 LOG.debug("Installing flows for router with internalvpnId");
896 //36 -> 46 ..Install flow forwarding packet to table46 from table36
897 LOG.debug("installTerminatingServiceTblEntry in naptswitch with dpnId {} for routerName {} with routerId {}",
898 naptSwitch, routerName,routerId);
899 externalRouterListener.installTerminatingServiceTblEntry(naptSwitch, routerName);
901 //Install default flows punting to controller in table 46(OutBoundNapt table)
902 LOG.debug("installOutboundMissEntry in naptswitch with dpnId {} for routerName {} with routerId {}",
903 naptSwitch, routerName, routerId);
904 externalRouterListener.createOutboundTblEntry(naptSwitch, routerId);
906 //Table 47 point to table 21 for inbound traffic
907 LOG.debug("installNaptPfibEntry in naptswitch with dpnId {} for router {}", naptSwitch, routerId);
908 externalRouterListener.installNaptPfibEntry(naptSwitch, routerId);
910 //36 -> 46 ..Install flow forwarding packet to table46 from table36
911 LOG.debug("installTerminatingServiceTblEntry in naptswitch with dpnId {} for routerName {} with BgpVpnId {}",
912 naptSwitch, routerName, routerVpnId);
913 externalRouterListener.installTerminatingServiceTblEntryWithUpdatedVpnId(naptSwitch, routerName, routerVpnId);
915 //Install default flows punting to controller in table 46(OutBoundNapt table)
916 LOG.debug("installOutboundMissEntry in naptswitch with dpnId {} for routerName {} with BgpVpnId {}",
917 naptSwitch, routerName, routerVpnId);
918 externalRouterListener.createOutboundTblEntryWithBgpVpn(naptSwitch, routerId, routerVpnId);
920 //Table 47 point to table 21 for inbound traffic
921 LOG.debug("installNaptPfibEntry in naptswitch with dpnId {} for router {} with BgpVpnId {}",
922 naptSwitch, routerId, routerVpnId);
923 externalRouterListener.installNaptPfibEntryWithBgpVpn(naptSwitch, routerId, routerVpnId);
926 String vpnName = getExtNetworkVpnName(routerId);
927 if(vpnName != null) {
928 //Table 47 point to table 21 for outbound traffic
929 long vpnId = NatUtil.getVpnId(dataBroker, vpnName);
931 LOG.debug("installNaptPfibEntry fin naptswitch with dpnId {} for BgpVpnId {}", naptSwitch, vpnId);
932 externalRouterListener.installNaptPfibEntry(naptSwitch, vpnId);
934 LOG.debug("Associated BgpvpnId not found for router {}",routerId);
937 //Install Fib entries for ExternalIps & program 36 -> 44
938 List<String> externalIps = NatUtil.getExternalIpsForRouter(dataBroker,routerId);
939 if (externalIps != null) {
940 for (String externalIp : externalIps) {
941 LOG.debug("advToBgpAndInstallFibAndTsFlows in naptswitch id {} with vpnName {} and externalIp {}",
942 naptSwitch, vpnName, externalIp);
943 externalRouterListener.advToBgpAndInstallFibAndTsFlows(naptSwitch, NatConstants.INBOUND_NAPT_TABLE,
944 vpnName, routerId, externalIp, vpnService, fibService, bgpManager, dataBroker, LOG);
945 LOG.debug("Successfully added fib entries in naptswitch {} for router {} with external IP {}", naptSwitch,
946 routerId, externalIp);
949 LOG.debug("External Ip not found for routerId {}",routerId);
952 LOG.debug("Associated vpnName not found for router {}",routerId);