Clean up MDSALManager exception handling
[netvirt.git] / natservice / impl / src / main / java / org / opendaylight / netvirt / natservice / internal / VxlanGreConntrackBasedSnatService.java
1 /*
2  * Copyright © 2017 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.netvirt.natservice.internal;
9
10 import java.math.BigInteger;
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.List;
14 import java.util.concurrent.ExecutionException;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
17 import org.opendaylight.genius.infra.Datastore.Configuration;
18 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
19 import org.opendaylight.genius.infra.TypedWriteTransaction;
20 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
21 import org.opendaylight.genius.mdsalutil.ActionInfo;
22 import org.opendaylight.genius.mdsalutil.BucketInfo;
23 import org.opendaylight.genius.mdsalutil.GroupEntity;
24 import org.opendaylight.genius.mdsalutil.InstructionInfo;
25 import org.opendaylight.genius.mdsalutil.MDSALUtil;
26 import org.opendaylight.genius.mdsalutil.MatchInfo;
27 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
28 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
29 import org.opendaylight.genius.mdsalutil.NwConstants;
30 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
31 import org.opendaylight.genius.mdsalutil.actions.ActionNxConntrack;
32 import org.opendaylight.genius.mdsalutil.actions.ActionNxConntrack.NxCtAction;
33 import org.opendaylight.genius.mdsalutil.actions.ActionNxLoadInPort;
34 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
35 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldMeta;
36 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldTunnelId;
37 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
38 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
39 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
40 import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Destination;
41 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
42 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
43 import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchCtState;
44 import org.opendaylight.netvirt.elanmanager.api.IElanService;
45 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
46 import org.opendaylight.netvirt.natservice.ha.NatDataUtil;
47 import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.types.rev160517.IpPrefixOrAddressBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.NxActionNatFlags;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.NxActionNatRangePresent;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
61
62 public class VxlanGreConntrackBasedSnatService extends ConntrackBasedSnatService {
63
64     private static final Logger LOG = LoggerFactory.getLogger(VxlanGreConntrackBasedSnatService.class);
65     private final ExternalRoutersListener externalRouterListener;
66     private final IElanService elanManager;
67
68     public VxlanGreConntrackBasedSnatService(DataBroker dataBroker, IMdsalApiManager mdsalManager,
69                                              ItmRpcService itmManager, OdlInterfaceRpcService odlInterfaceRpcService,
70                                              IdManagerService idManager, NAPTSwitchSelector naptSwitchSelector,
71                                              ExternalRoutersListener externalRouterListener, IElanService elanManager,
72                                              IInterfaceManager interfaceManager,
73                                              IVpnFootprintService vpnFootprintService,
74                                              IFibManager fibManager, NatDataUtil natDataUtil,
75                                              DataTreeEventCallbackRegistrar eventCallbacks) {
76         super(dataBroker, mdsalManager, itmManager, idManager, naptSwitchSelector, odlInterfaceRpcService,
77                 interfaceManager, vpnFootprintService, fibManager, natDataUtil, eventCallbacks);
78         this.externalRouterListener = externalRouterListener;
79         this.elanManager = elanManager;
80     }
81
82     @Override
83     public boolean addSnatAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
84         BigInteger primarySwitchId) {
85         ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
86         LOG.debug("VxlanGreConntrackBasedSnatService: handleSnatAllSwitch ProviderTypes {}", extNwProviderType);
87         if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
88             LOG.debug("handleSnatAllSwitch : Skip FLAT/VLAN provider networks.");
89             return true;
90         }
91         return super.addSnatAllSwitch(confTx, routers, primarySwitchId);
92     }
93
94     @Override
95     public boolean removeSnatAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
96             BigInteger primarySwitchId) throws ExecutionException, InterruptedException {
97         ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
98         LOG.debug("VxlanGreConntrackBasedSnatService: handleSnatAllSwitch ProviderTypes {}", extNwProviderType);
99         if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
100             LOG.debug("handleSnatAllSwitch : Skip FLAT/VLAN provider networks.");
101             return true;
102         }
103         return super.removeSnatAllSwitch(confTx, routers, primarySwitchId);
104     }
105
106     @Override
107     public boolean addSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
108         BigInteger primarySwitchId, BigInteger dpnId) {
109         ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
110         LOG.debug("VxlanGreConntrackBasedSnatService: handleSnat ProviderTypes {}", extNwProviderType);
111         if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
112             LOG.debug("handleSnat : Skip FLAT/VLAN provider networks.");
113             return true;
114         }
115         return super.addSnat(confTx, routers, primarySwitchId, dpnId);
116     }
117
118     @Override
119     public boolean removeSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
120             BigInteger primarySwitchId, BigInteger dpnId) throws ExecutionException, InterruptedException {
121         ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
122         LOG.debug("VxlanGreConntrackBasedSnatService: handleSnat ProviderTypes {}", extNwProviderType);
123         if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
124             LOG.debug("handleSnat : Skip FLAT/VLAN provider networks.");
125             return true;
126         }
127         return super.removeSnat(confTx, routers, primarySwitchId, dpnId);
128     }
129
130     @Override
131     protected void addSnatSpecificEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
132         BigInteger dpnId) {
133
134         LOG.info("installSnatSpecificEntriesForNaptSwitch for router {}",
135             routers.getRouterName());
136         String routerName = routers.getRouterName();
137         Long routerId = NatUtil.getVpnId(dataBroker, routerName);
138         int elanId = NatUtil.getElanInstanceByName(routers.getNetworkId().getValue(), dataBroker)
139             .getElanTag().intValue();
140         /* Install Outbound NAT entries */
141
142         addSnatMissEntryForPrimrySwch(confTx, dpnId, routerId, elanId);
143         addTerminatingServiceTblEntryForVxlanGre(confTx, dpnId, routerName, routerId, elanId);
144         //Long extNetVpnId = NatUtil.getNetworkVpnIdFromRouterId(dataBroker, routerId);
145         Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, routers.getNetworkId());
146         if (vpnUuid == null) {
147             LOG.error("installSnatSpecificEntriesForNaptSwitch: Unable to retrieve external vpn_id for "
148                 + "external network {} with routerId {}", routers.getNetworkId(), routerId);
149             return;
150         }
151         Long extNetVpnId = NatUtil.getVpnId(dataBroker, vpnUuid.getValue());
152         LOG.info("installSnatSpecificEntriesForNaptSwitch: external network vpn_id {} for router {}",
153             extNetVpnId, routers.getRouterName());
154         List<ExternalIps> externalIps = routers.getExternalIps();
155         addOutboundTblTrackEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId);
156         addOutboundTblEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId, externalIps, elanId);
157         addNaptPfibFlowForVxlanGre(confTx, routers, dpnId, extNetVpnId);
158         addNaptPfibEntry(confTx, dpnId, routerId);
159
160         //Install Inbound NAT entries
161         addInboundEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId, externalIps, elanId);
162         if (externalIps.isEmpty()) {
163             LOG.error("installSnatSpecificEntriesForNaptSwitch: No externalIP present for router {}",
164                 routerName);
165             return;
166         }
167         //The logic now handle only one external IP per router, others if present will be ignored.
168         String externalIp = NatUtil.validateAndAddNetworkMask(externalIps.get(0).getIpAddress());
169         externalRouterListener.handleSnatReverseTraffic(confTx, dpnId, routers, routerId, routerName, externalIp);
170     }
171
172     @Override
173     protected void removeSnatSpecificEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
174             Routers routers, BigInteger dpnId) throws ExecutionException, InterruptedException {
175
176         LOG.info("installSnatSpecificEntriesForNaptSwitch for router {}",
177             routers.getRouterName());
178         String routerName = routers.getRouterName();
179         Long routerId = NatUtil.getVpnId(dataBroker, routerName);
180
181         /* Remove Outbound NAT entries */
182         removeSnatMissEntryForPrimrySwch(confTx, dpnId, routerId);
183         removeTerminatingServiceTblEntryForVxlanGre(confTx, dpnId, routerId);
184         //Long extNetVpnId = NatUtil.getNetworkVpnIdFromRouterId(dataBroker, routerId);
185         Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, routers.getNetworkId());
186         if (vpnUuid == null) {
187             LOG.error("installSnatSpecificEntriesForNaptSwitch: Unable to retrieve external vpn_id for "
188                 + "external network {} with routerId {}", routers.getNetworkId(), routerId);
189             return;
190         }
191         Long extNetVpnId = NatUtil.getVpnId(dataBroker, vpnUuid.getValue());
192         LOG.info("installSnatSpecificEntriesForNaptSwitch: external network vpn_id {} for router {}",
193             extNetVpnId, routers.getRouterName());
194         List<ExternalIps> externalIps = routers.getExternalIps();
195         removeOutboundTblTrackEntryForVxlanGre(confTx, dpnId, routerId);
196         removeOutboundTblEntryForVxlanGre(confTx, dpnId, routerId, externalIps);
197         removeNaptPfibFlowForVxlanGre(confTx, routers, dpnId, extNetVpnId);
198         removeNaptPfibEntry(confTx, dpnId, routerId);
199
200         //Install Inbound NAT entries
201         removeInboundEntryForVxlanGre(confTx, dpnId, routerId, externalIps);
202         if (externalIps.isEmpty()) {
203             LOG.error("installSnatSpecificEntriesForNaptSwitch: No externalIP present for router {}",
204                 routerName);
205             return;
206         }
207         //The logic now handle only one external IP per router, others if present will be ignored.
208         String externalIp = NatUtil.validateAndAddNetworkMask(externalIps.get(0).getIpAddress());
209         externalRouterListener.clearFibTsAndReverseTraffic(dpnId, routerId, routers.getNetworkId(),
210             Collections.singletonList(externalIp), null, routers.getExtGwMacAddress(), confTx);
211     }
212
213     protected void addOutboundTblTrackEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
214         Long routerId, Long extNetVpnId) {
215         LOG.info("createOutboundTblTrackEntryForVxlanGre: Install Outbound tracking table flow on dpId {} for "
216                 + "routerId {}", dpnId, routerId);
217         List<MatchInfoBase> matches = new ArrayList<>();
218         matches.add(MatchEthernetType.IPV4);
219         matches.add(new NxMatchCtState(SNAT_CT_STATE, SNAT_CT_STATE_MASK));
220         matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
221
222         ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
223         ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil.getVpnIdMetadata(extNetVpnId));
224         listActionInfo.add(actionSetFieldMeta);
225         ArrayList<InstructionInfo> instructionInfo = new ArrayList<>();
226         listActionInfo.add(new ActionNxResubmit(NwConstants.NAPT_PFIB_TABLE));
227         instructionInfo.add(new InstructionApplyActions(listActionInfo));
228
229         String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId) + "trkest";
230         addFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY, flowRef,
231                 NwConstants.COOKIE_SNAT_TABLE, matches, instructionInfo);
232
233     }
234
235     protected void removeOutboundTblTrackEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx,
236             BigInteger dpnId, Long routerId) throws ExecutionException, InterruptedException {
237         LOG.info("createOutboundTblTrackEntryForVxlanGre: Install Outbound tracking table flow on dpId {} for "
238             + "routerId {}", dpnId, routerId);
239
240         String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId) + "trkest";
241         removeFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
242
243     }
244
245     protected void addOutboundTblEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
246         long routerId, Long extNetVpnId, List<ExternalIps> externalIps, int elanId) {
247         LOG.info("createOutboundTblEntryForVxlanGre: Install Outbound table flow on dpId {} for routerId {}", dpnId,
248                 routerId);
249         List<MatchInfoBase> matches = new ArrayList<>();
250         matches.add(MatchEthernetType.IPV4);
251         matches.add(new NxMatchCtState(TRACKED_NEW_CT_STATE, TRACKED_NEW_CT_MASK));
252         matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
253         if (externalIps.isEmpty()) {
254             LOG.error("createOutboundTblEntryForVxlanGre: No externalIP present for routerId {}",
255                     routerId);
256             return;
257         }
258         //The logic now handle only one external IP per router, others if present will be ignored.
259         String externalIp = externalIps.get(0).getIpAddress();
260         List<ActionInfo> actionsInfos = new ArrayList<>();
261         ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
262                 .getVpnIdMetadata(extNetVpnId));
263         actionsInfos.add(actionSetFieldMeta);
264         List<ActionNxConntrack.NxCtAction> ctActionsListCommit = new ArrayList<>();
265         int rangePresent = NxActionNatRangePresent.NXNATRANGEIPV4MIN.getIntValue();
266         int flags = NxActionNatFlags.NXNATFSRC.getIntValue();
267         ActionNxConntrack.NxCtAction nxCtActionCommit = new ActionNxConntrack.NxNat(0, flags, rangePresent,
268             IpPrefixOrAddressBuilder.getDefaultInstance(externalIp).getIpAddress(), null,0, 0);
269         ctActionsListCommit.add(nxCtActionCommit);
270         int ctCommitFlag = 1;
271         ActionNxConntrack actionNxConntrackSubmit = new ActionNxConntrack(ctCommitFlag, 0, elanId,
272                 NwConstants.NAPT_PFIB_TABLE, ctActionsListCommit);
273         actionsInfos.add(actionNxConntrackSubmit);
274         List<InstructionInfo> instructions = new ArrayList<>();
275         instructions.add(new InstructionApplyActions(actionsInfos));
276         String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
277         addFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef,  NatConstants.SNAT_NEW_FLOW_PRIORITY,
278                 flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
279     }
280
281     protected void removeOutboundTblEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
282             long routerId, List<ExternalIps> externalIps) throws ExecutionException, InterruptedException {
283         LOG.info("createOutboundTblEntryForVxlanGre: Install Outbound table flow on dpId {} for routerId {}", dpnId,
284             routerId);
285         if (externalIps.isEmpty()) {
286             LOG.error("createOutboundTblEntryForVxlanGre: No externalIP present for routerId {}",
287                 routerId);
288             return;
289         }
290         //The logic now handle only one external IP per router, others if present will be ignored.
291         String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
292         removeFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
293     }
294
295     protected void addNaptPfibFlowForVxlanGre(TypedWriteTransaction<Configuration> confTx, Routers routers,
296         BigInteger dpnId, Long extNetVpnId) {
297         LOG.info("installNaptPfibFlowForVxlanGre: Install Napt preFibFlow on dpId {} with matching extNetVpnId {} "
298                 + "for router {}", dpnId, extNetVpnId, routers.getRouterName());
299         List<MatchInfoBase> matches = new ArrayList<>();
300         matches.add(MatchEthernetType.IPV4);
301         matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNetVpnId),
302                 MetaDataUtil.METADATA_MASK_VRFID));
303         ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
304         ArrayList<InstructionInfo> instructions = new ArrayList<>();
305         listActionInfo.add(new ActionNxLoadInPort(BigInteger.ZERO));
306         listActionInfo.add(new ActionNxResubmit(NwConstants.L3_FIB_TABLE));
307         instructions.add(new InstructionApplyActions(listActionInfo));
308         String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, extNetVpnId);
309         addFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY,
310                 flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
311     }
312
313     protected void removeNaptPfibFlowForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
314             BigInteger dpnId, Long extNetVpnId) throws ExecutionException, InterruptedException {
315         LOG.info("installNaptPfibFlowForVxlanGre: Install Napt preFibFlow on dpId {} with matching extNetVpnId {} "
316             + "for router {}", dpnId, extNetVpnId, routers.getRouterName());
317         String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, extNetVpnId);
318         removeFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef);
319     }
320
321     protected void addInboundEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
322         long routerId, Long extNeVpnId, List<ExternalIps> externalIps, int elanId) {
323         LOG.info("installInboundEntryForVxlanGre:  Install Inbound table entry on dpId {} for routerId {}",
324                 dpnId, routerId);
325         List<MatchInfoBase> matches = new ArrayList<>();
326         matches.add(MatchEthernetType.IPV4);
327         if (externalIps.isEmpty()) {
328             LOG.error("installInboundEntryForVxlanGre : createInboundTblEntry no externalIP present for routerId {}",
329                     routerId);
330             return;
331         }
332         String externalIp = externalIps.get(0).getIpAddress();
333         matches.add(new MatchIpv4Destination(externalIp,"32"));
334         matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNeVpnId), MetaDataUtil.METADATA_MASK_VRFID));
335         List<ActionInfo> actionsInfos = new ArrayList<>();
336         List<ActionNxConntrack.NxCtAction> ctActionsList = new ArrayList<>();
337         ActionNxConntrack.NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
338         ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
339                 .getVpnIdMetadata(routerId));
340         actionsInfos.add(actionSetFieldMeta);
341         ctActionsList.add(nxCtAction);
342         ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
343                 .NAPT_PFIB_TABLE,ctActionsList);
344
345         actionsInfos.add(actionNxConntrack);
346         List<InstructionInfo> instructions = new ArrayList<>();
347         instructions.add(new InstructionApplyActions(actionsInfos));
348         String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
349         addFlow(confTx, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY, flowRef,
350                 NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
351     }
352
353     protected void removeInboundEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
354             long routerId, List<ExternalIps> externalIps) throws ExecutionException, InterruptedException {
355         LOG.info("removeInboundEntryForVxlanGre: remove Inbound table entry on dpId {} for routerId {}",
356             dpnId, routerId);
357         if (externalIps.isEmpty()) {
358             LOG.error("removeInboundEntryForVxlanGre : createInboundTblEntry no externalIP present for routerId {}",
359                 routerId);
360             return;
361         }
362
363         String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
364         removeFlow(confTx, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef);
365     }
366
367     protected void addTerminatingServiceTblEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx,
368         BigInteger dpnId, String routerName, Long routerId, int elanId) {
369         LOG.info("installTerminatingServiceTblEntryForVxlanGre : creating entry for"
370                 + "Terminating Service Table for switch {}, routerId {}", dpnId, routerId);
371         List<MatchInfo> matches = new ArrayList<>();
372         matches.add(MatchEthernetType.IPV4);
373
374         BigInteger tunnelId = BigInteger.valueOf(routerId);
375         if (elanManager.isOpenStackVniSemanticsEnforced()) {
376             tunnelId = NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId);
377         }
378         matches.add(new MatchTunnelId(tunnelId));
379
380         List<ActionInfo> actionsInfos = new ArrayList<>();
381         List<NxCtAction> ctActionsList = new ArrayList<>();
382         NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
383         ctActionsList.add(nxCtAction);
384         ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
385                 .OUTBOUND_NAPT_TABLE,ctActionsList);
386         ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
387                 .getVpnIdMetadata(routerId.longValue()));
388         actionsInfos.add(actionSetFieldMeta);
389         actionsInfos.add(actionNxConntrack);
390         List<InstructionInfo> instructions = new ArrayList<>();
391         instructions.add(new InstructionApplyActions(actionsInfos));
392         String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId.longValue());
393         addFlow(confTx, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY,
394             flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
395
396     }
397
398     protected void removeTerminatingServiceTblEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx,
399             BigInteger dpnId, Long routerId) throws ExecutionException, InterruptedException {
400         LOG.info("removeTerminatingServiceTblEntryForVxlanGre : removing entry for"
401             + "Terminating Service Table for switch {}, routerId {}", dpnId, routerId);
402
403         String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId.longValue());
404         removeFlow(confTx, dpnId,  NwConstants.INTERNAL_TUNNEL_TABLE, flowRef);
405
406     }
407
408     @Override
409     protected void addSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId, Long routerId,
410         String routerName, BigInteger primarySwitchId) {
411         LOG.debug("installSnatMissEntry : Installing SNAT miss entry in switch {}", dpnId);
412         List<ActionInfo> listActionInfoPrimary = new ArrayList<>();
413         String ifNamePrimary = getTunnelInterfaceName(dpnId, primarySwitchId);
414         List<BucketInfo> listBucketInfo = new ArrayList<>();
415         if (ifNamePrimary != null) {
416             LOG.debug("installSnatMissEntry : On Non- Napt switch , Primary Tunnel interface is {}", ifNamePrimary);
417             listActionInfoPrimary = NatUtil.getEgressActionsForInterface(odlInterfaceRpcService, itmManager,
418                     interfaceManager, ifNamePrimary, routerId, true);
419         }
420         BucketInfo bucketPrimary = new BucketInfo(listActionInfoPrimary);
421         listBucketInfo.add(0, bucketPrimary);
422         LOG.debug("installSnatMissEntry : installSnatMissEntry called for dpnId {} with primaryBucket {} ", dpnId,
423                 listBucketInfo.get(0));
424         // Install the select group
425         long groupId = createGroupId(getGroupIdKey(routerName));
426         GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName, GroupTypes.GroupAll,
427                 listBucketInfo);
428         LOG.debug("installSnatMissEntry : installing the SNAT to NAPT GroupEntity:{}", groupEntity);
429         mdsalManager.addGroup(confTx, groupEntity);
430         // Install miss entry pointing to group
431         LOG.debug("installSnatMissEntry : buildSnatFlowEntity is called for dpId {}, routerName {} and groupId {}",
432                 dpnId, routerName, groupId);
433         List<MatchInfo> matches = new ArrayList<>();
434         matches.add(new MatchEthernetType(0x0800L));
435         matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
436
437         List<ActionInfo> actionsInfo = new ArrayList<>();
438
439         BigInteger tunnelId = BigInteger.valueOf(routerId);
440         if (elanManager.isOpenStackVniSemanticsEnforced()) {
441             tunnelId = NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId);
442         }
443
444         actionsInfo.add(new ActionSetFieldTunnelId(tunnelId));
445         LOG.debug("AbstractSnatService : Setting the tunnel to the list of action infos {}", actionsInfo);
446         actionsInfo.add(new ActionGroup(groupId));
447         List<InstructionInfo> instructions = new ArrayList<>();
448         instructions.add(new InstructionApplyActions(actionsInfo));
449         String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
450         addFlow(confTx, dpnId, NwConstants.PSNAT_TABLE, flowRef,  NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef,
451                 NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
452     }
453
454     @Override
455     protected void removeSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
456             Long routerId, String routerName) throws ExecutionException, InterruptedException {
457         LOG.debug("installSnatMissEntry : Removing SNAT miss entry in switch {}", dpnId);
458
459         String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
460         removeFlow(confTx, dpnId, NwConstants.PSNAT_TABLE, flowRef);
461     }
462
463 }