Datastore txes: natservice, AbstractSnatService
[netvirt.git] / natservice / impl / src / main / java / org / opendaylight / netvirt / natservice / internal / ConntrackBasedSnatService.java
1 /*
2  * Copyright (c) 2017 Red Hat, Inc. 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 com.google.common.base.Optional;
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.List;
14 import org.apache.commons.lang3.tuple.ImmutablePair;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.genius.infra.Datastore.Configuration;
17 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
18 import org.opendaylight.genius.infra.TypedWriteTransaction;
19 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
20 import org.opendaylight.genius.mdsalutil.ActionInfo;
21 import org.opendaylight.genius.mdsalutil.InstructionInfo;
22 import org.opendaylight.genius.mdsalutil.MatchInfo;
23 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
24 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
25 import org.opendaylight.genius.mdsalutil.NWUtil;
26 import org.opendaylight.genius.mdsalutil.NwConstants;
27 import org.opendaylight.genius.mdsalutil.actions.ActionNxConntrack;
28 import org.opendaylight.genius.mdsalutil.actions.ActionNxConntrack.NxCtAction;
29 import org.opendaylight.genius.mdsalutil.actions.ActionNxLoadInPort;
30 import org.opendaylight.genius.mdsalutil.actions.ActionNxLoadMetadata;
31 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
32 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldEthernetSource;
33 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
34 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
35 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
36 import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Destination;
37 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
38 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
39 import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchCtState;
40 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
41 import org.opendaylight.netvirt.natservice.ha.NatDataUtil;
42 import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.IpAddresses;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.Subnets;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.types.rev160517.IpPrefixOrAddress;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.NxActionNatFlags;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.NxActionNatRangePresent;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
56
57 public abstract class ConntrackBasedSnatService extends AbstractSnatService {
58     private static final Logger LOG = LoggerFactory.getLogger(ConntrackBasedSnatService.class);
59
60     protected static final int TRACKED_NEW_CT_STATE = 0x21;
61     protected static final int TRACKED_NEW_CT_MASK = 0x21;
62     protected static final int SNAT_CT_STATE = 0x40;
63     protected static final int SNAT_CT_STATE_MASK = 0x40;
64     protected static final int DNAT_CT_STATE = 0x80;
65     protected static final int DNAT_CT_STATE_MASK = 0x80;
66
67     public ConntrackBasedSnatService(DataBroker dataBroker, IMdsalApiManager mdsalManager, ItmRpcService itmManager,
68                                      IdManagerService idManager, NAPTSwitchSelector naptSwitchSelector,
69                                      OdlInterfaceRpcService odlInterfaceRpcService,
70                                      IInterfaceManager interfaceManager, IVpnFootprintService vpnFootprintService,
71                                      IFibManager fibManager, NatDataUtil natDataUtil) {
72         super(dataBroker, mdsalManager, itmManager, odlInterfaceRpcService, idManager, naptSwitchSelector,
73                 interfaceManager, vpnFootprintService, fibManager, natDataUtil);
74     }
75
76     @Override
77     protected void addSnatSpecificEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
78         Routers routers, BigInteger dpnId) {
79         LOG.info("installSnatSpecificEntriesForNaptSwitch: called for router {}",
80             routers.getRouterName());
81         String routerName = routers.getRouterName();
82         Long routerId = NatUtil.getVpnId(confTx, routerName);
83         int elanId = NatUtil.getElanInstanceByName(confTx, routers.getNetworkId().getValue())
84             .getElanTag().intValue();
85         if (routerId == NatConstants.INVALID_ID) {
86             LOG.error("InvalidRouterId: unable to installSnatSpecificEntriesForNaptSwitch on dpn {}", dpnId);
87             return;
88         }
89         /* Install Outbound NAT entries */
90
91         addSnatMissEntryForPrimrySwch(confTx, dpnId, routerId, elanId);
92         addTerminatingServiceTblEntry(confTx, dpnId, routerId, elanId);
93
94         String extGwMacAddress = NatUtil.getExtGwMacAddFromRouterName(confTx, routerName);
95         addOutboundTblTrackEntry(confTx, dpnId, routerId, extGwMacAddress);
96         for (ExternalIps externalIp : routers.getExternalIps()) {
97             if (!NWUtil.isIpv4Address(externalIp.getIpAddress())) {
98                 // In this class we handle only IPv4 use-cases.
99                 continue;
100             }
101             //The logic now handle only one external IP per router, others if present will be ignored.
102             long extSubnetId = NatUtil.getExternalSubnetVpnId(confTx, externalIp.getSubnetId());
103             addOutboundTblEntry(confTx, dpnId, routerId, externalIp.getIpAddress(), elanId, extGwMacAddress);
104             addNaptPfibFlow(confTx, routers, dpnId, routerId, extSubnetId);
105
106             //Install Inbound NAT entries
107             addInboundEntry(confTx, dpnId, routerId, externalIp.getIpAddress(), elanId, extSubnetId);
108             addNaptPfibEntry(confTx, dpnId, routerId);
109
110             String fibExternalIp = NatUtil.validateAndAddNetworkMask(externalIp.getIpAddress());
111             Optional<Subnets> externalSubnet = NatUtil.getOptionalExternalSubnets(confTx, externalIp.getSubnetId());
112             if (externalSubnet.isPresent()) {
113                 String externalVpn =  externalIp.getSubnetId().getValue();
114                 String vpnRd = NatUtil.getVpnRd(confTx, externalVpn);
115                 vpnFootprintService.updateVpnToDpnMapping(dpnId, externalVpn, vpnRd, null /* interfaceName*/,
116                     new ImmutablePair<>(IpAddresses.IpAddressSource.ExternalFixedIP, fibExternalIp),
117                     true);
118             }
119             break;
120         }
121     }
122
123     @Override
124     protected void removeSnatSpecificEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
125         Routers routers, BigInteger dpnId) {
126         LOG.info("installSnatSpecificEntriesForNaptSwitch: called for router {}",
127             routers.getRouterName());
128         String routerName = routers.getRouterName();
129         Long routerId = NatUtil.getVpnId(confTx, routerName);
130         if (routerId == NatConstants.INVALID_ID) {
131             LOG.error("InvalidRouterId: unable to installSnatSpecificEntriesForNaptSwitch on dpn {}", dpnId);
132             return;
133         }
134         /* Remove Outbound NAT entries */
135
136         removeSnatMissEntryForPrimrySwch(confTx, dpnId, routerId);
137         removeTerminatingServiceTblEntry(confTx, dpnId, routerId);
138
139         removeOutboundTblTrackEntry(confTx, dpnId, routerId);
140         for (ExternalIps externalIp : routers.getExternalIps()) {
141             if (!NWUtil.isIpv4Address(externalIp.getIpAddress())) {
142                 // In this class we handle only IPv4 use-cases.
143                 continue;
144             }
145             //The logic now handle only one external IP per router, others if present will be ignored.
146             removeOutboundTblEntry(confTx, dpnId, routerId);
147             removeNaptPfibFlow(confTx, routers, dpnId, routerId);
148
149             //Install Inbound NAT entries
150             removeInboundEntry(confTx, dpnId, routerId);
151             removeNaptPfibEntry(confTx, dpnId, routerId);
152
153             String fibExternalIp = NatUtil.validateAndAddNetworkMask(externalIp.getIpAddress());
154             Optional<Subnets> externalSubnet = NatUtil.getOptionalExternalSubnets(confTx, externalIp.getSubnetId());
155             if (externalSubnet.isPresent()) {
156                 String externalVpn =  externalIp.getSubnetId().getValue();
157                 String vpnRd = NatUtil.getVpnRd(confTx, externalVpn);
158                 vpnFootprintService.updateVpnToDpnMapping(dpnId, externalVpn, vpnRd, null /* interfaceName*/,
159                     new ImmutablePair<>(IpAddresses.IpAddressSource.ExternalFixedIP, fibExternalIp),
160                     false);
161             }
162             break;
163         }
164     }
165
166     @Override
167     protected void addSnatSpecificEntriesForNonNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
168         Routers routers, BigInteger dpnId) {
169         // Nothing to to do here
170     }
171
172     @Override
173     protected void removeSnatSpecificEntriesForNonNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
174         Routers routers, BigInteger dpnId) {
175         // Nothing to to do here
176     }
177
178     protected void addSnatMissEntryForPrimrySwch(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
179         Long routerId, int elanId) {
180         LOG.info("installSnatSpecificEntriesForNaptSwitch : called for the primary NAPT switch dpnId {}", dpnId);
181         List<MatchInfo> matches = new ArrayList<>();
182         matches.add(MatchEthernetType.IPV4);
183         matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
184         List<InstructionInfo> instructions = new ArrayList<>();
185         List<ActionInfo> actionsInfos = new ArrayList<>();
186         List<NxCtAction> ctActionsList = new ArrayList<>();
187         NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
188         ctActionsList.add(nxCtAction);
189         ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId,
190                 NwConstants.OUTBOUND_NAPT_TABLE,ctActionsList);
191
192         actionsInfos.add(actionNxConntrack);
193         instructions.add(new InstructionApplyActions(actionsInfos));
194
195         String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
196         addFlow(confTx, dpnId, NwConstants.PSNAT_TABLE, flowRef, NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef,
197                 NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
198     }
199
200     protected void removeSnatMissEntryForPrimrySwch(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
201         Long routerId) {
202         LOG.info("installSnatSpecificEntriesForNaptSwitch : called for the primary NAPT switch dpnId {}", dpnId);
203
204         String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
205         removeFlow(confTx, dpnId, NwConstants.PSNAT_TABLE, flowRef);
206     }
207
208     protected void addTerminatingServiceTblEntry(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
209         Long routerId, int elanId) {
210         LOG.info("installTerminatingServiceTblEntry : creating entry for Terminating Service Table "
211                 + "for switch {}, routerId {}", dpnId, routerId);
212         List<MatchInfo> matches = new ArrayList<>();
213         matches.add(MatchEthernetType.IPV4);
214         matches.add(new MatchTunnelId(BigInteger.valueOf(routerId)));
215
216         List<ActionInfo> actionsInfos = new ArrayList<>();
217         List<NxCtAction> ctActionsList = new ArrayList<>();
218         NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
219         ctActionsList.add(nxCtAction);
220         ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
221                 .OUTBOUND_NAPT_TABLE,ctActionsList);
222         ActionNxLoadMetadata actionLoadMeta = new ActionNxLoadMetadata(MetaDataUtil
223                 .getVpnIdMetadata(routerId), LOAD_START, LOAD_END);
224         actionsInfos.add(actionLoadMeta);
225         actionsInfos.add(actionNxConntrack);
226         List<InstructionInfo> instructions = new ArrayList<>();
227         instructions.add(new InstructionApplyActions(actionsInfos));
228         String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId);
229         addFlow(confTx, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY,
230             flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
231     }
232
233     protected void removeTerminatingServiceTblEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
234         Long routerId) {
235         LOG.info("installTerminatingServiceTblEntry : creating entry for Terminating Service Table "
236             + "for switch {}, routerId {}", dpnId, routerId);
237
238         String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId);
239         removeFlow(confTx, dpnId,  NwConstants.INTERNAL_TUNNEL_TABLE, flowRef);
240     }
241
242     protected void addOutboundTblTrackEntry(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
243         Long routerId, String extGwMacAddress) {
244         LOG.info("createOutboundTblTrackEntry : called for switch {}, routerId {}", dpnId, routerId);
245         List<MatchInfoBase> matches = new ArrayList<>();
246         matches.add(MatchEthernetType.IPV4);
247         matches.add(new NxMatchCtState(SNAT_CT_STATE, SNAT_CT_STATE_MASK));
248         matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
249         ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
250         listActionInfo.add(new ActionSetFieldEthernetSource(new MacAddress(extGwMacAddress)));
251         ArrayList<InstructionInfo> instructionInfo = new ArrayList<>();
252         listActionInfo.add(new ActionNxResubmit(NwConstants.NAPT_PFIB_TABLE));
253         instructionInfo.add(new InstructionApplyActions(listActionInfo));
254
255         String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId) + "trkest";
256         addFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY, flowRef,
257                 NwConstants.COOKIE_SNAT_TABLE, matches, instructionInfo);
258     }
259
260     protected void removeOutboundTblTrackEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
261         Long routerId) {
262         LOG.info("createOutboundTblTrackEntry : called for switch {}, routerId {}", dpnId, routerId);
263
264         String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId) + "trkest";
265         removeFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
266     }
267
268     protected void addOutboundTblEntry(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId, long routerId,
269         String externalIp, int elanId, String extGwMacAddress) {
270         LOG.info("createOutboundTblEntry : dpId {} and routerId {}", dpnId, routerId);
271         List<MatchInfoBase> matches = new ArrayList<>();
272         matches.add(MatchEthernetType.IPV4);
273         matches.add(new NxMatchCtState(TRACKED_NEW_CT_STATE, TRACKED_NEW_CT_MASK));
274         matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
275         List<ActionInfo> actionsInfos = new ArrayList<>();
276         actionsInfos.add(new ActionSetFieldEthernetSource(new MacAddress(extGwMacAddress)));
277         List<NxCtAction> ctActionsListCommit = new ArrayList<>();
278         int rangePresent = NxActionNatRangePresent.NXNATRANGEIPV4MIN.getIntValue();
279         int flags = NxActionNatFlags.NXNATFSRC.getIntValue();
280         NxCtAction nxCtActionCommit = new ActionNxConntrack.NxNat(0, flags, rangePresent,
281             new IpPrefixOrAddress(externalIp.toCharArray()).getIpAddress(),
282             null,0, 0);
283         ctActionsListCommit.add(nxCtActionCommit);
284         int ctCommitFlag = 1;
285         ActionNxConntrack actionNxConntrackSubmit = new ActionNxConntrack(ctCommitFlag, 0, elanId,
286             NwConstants.NAPT_PFIB_TABLE, ctActionsListCommit);
287         actionsInfos.add(actionNxConntrackSubmit);
288         List<InstructionInfo> instructions = new ArrayList<>();
289         instructions.add(new InstructionApplyActions(actionsInfos));
290         String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
291         addFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef,  NatConstants.SNAT_NEW_FLOW_PRIORITY,
292             flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
293     }
294
295     protected void removeOutboundTblEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
296         long routerId) {
297         LOG.info("createOutboundTblEntry : dpId {} and routerId {}", dpnId, routerId);
298         String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
299         removeFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
300     }
301
302     protected void addNaptPfibFlow(TypedReadWriteTransaction<Configuration> confTx, Routers routers, BigInteger dpnId,
303         long routerId, long extSubnetId) {
304         Long extNetId = NatUtil.getVpnId(confTx, routers.getNetworkId().getValue());
305         LOG.info("installNaptPfibFlow : dpId {}, extNetId {}", dpnId, extNetId);
306         List<MatchInfoBase> matches = new ArrayList<>();
307         matches.add(MatchEthernetType.IPV4);
308         matches.add(new NxMatchCtState(SNAT_CT_STATE, SNAT_CT_STATE_MASK));
309         matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
310         List<ActionInfo> listActionInfo = new ArrayList<>();
311         if (extSubnetId == NatConstants.INVALID_ID) {
312             LOG.error("installNaptPfibFlow : external subnet id is invalid.");
313             return;
314         }
315         ActionNxLoadMetadata actionLoadMeta = new ActionNxLoadMetadata(MetaDataUtil
316             .getVpnIdMetadata(extSubnetId), LOAD_START, LOAD_END);
317         listActionInfo.add(actionLoadMeta);
318         ArrayList<InstructionInfo> instructions = new ArrayList<>();
319         listActionInfo.add(new ActionNxLoadInPort(BigInteger.ZERO));
320         listActionInfo.add(new ActionNxResubmit(NwConstants.L3_FIB_TABLE));
321         instructions.add(new InstructionApplyActions(listActionInfo));
322         String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, routerId);
323         flowRef = flowRef + "OUTBOUND";
324         addFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY,
325             flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
326     }
327
328     protected void removeNaptPfibFlow(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
329         BigInteger dpnId, long routerId) {
330         Long extNetId = NatUtil.getVpnId(confTx, routers.getNetworkId().getValue());
331         LOG.info("installNaptPfibFlow : dpId {}, extNetId {}", dpnId, extNetId);
332         String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, routerId) + "OUTBOUND";
333         removeFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef);
334     }
335
336     protected void addInboundEntry(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId, long routerId,
337         String externalIp, int elanId, long extSubnetId) {
338         LOG.info("installInboundEntry : dpId {} and routerId {}", dpnId, routerId);
339         List<MatchInfoBase> matches = new ArrayList<>();
340         matches.add(MatchEthernetType.IPV4);
341         matches.add(new MatchIpv4Destination(externalIp,"32"));
342         if (extSubnetId == NatConstants.INVALID_ID) {
343             LOG.error("installInboundEntry : external subnet id is invalid.");
344             return;
345         }
346         matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extSubnetId),
347             MetaDataUtil.METADATA_MASK_VRFID));
348         List<ActionInfo> actionsInfos = new ArrayList<>();
349         List<NxCtAction> ctActionsList = new ArrayList<>();
350         NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
351         ActionNxLoadMetadata actionLoadMeta = new ActionNxLoadMetadata(MetaDataUtil
352             .getVpnIdMetadata(routerId), LOAD_START, LOAD_END);
353         actionsInfos.add(actionLoadMeta);
354         ctActionsList.add(nxCtAction);
355         ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
356             .NAPT_PFIB_TABLE,ctActionsList);
357
358         actionsInfos.add(actionNxConntrack);
359         List<InstructionInfo> instructions = new ArrayList<>();
360         instructions.add(new InstructionApplyActions(actionsInfos));
361         String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
362         flowRef = flowRef + "OUTBOUND";
363         addFlow(confTx, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY, flowRef,
364             NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
365     }
366
367     protected void removeInboundEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
368         long routerId) {
369         LOG.info("installInboundEntry : dpId {} and routerId {}", dpnId, routerId);
370
371         String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId) + "OUTBOUND";
372         removeFlow(confTx, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef);
373     }
374
375     protected void addNaptPfibEntry(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId, long routerId) {
376         LOG.info("installNaptPfibEntry : called for dpnId {} and routerId {} ", dpnId, routerId);
377         List<MatchInfoBase> matches = new ArrayList<>();
378         matches.add(MatchEthernetType.IPV4);
379         matches.add(new NxMatchCtState(DNAT_CT_STATE, DNAT_CT_STATE_MASK));
380         matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
381
382         ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
383         ArrayList<InstructionInfo> instructionInfo = new ArrayList<>();
384         listActionInfo.add(new ActionNxLoadInPort(BigInteger.ZERO));
385         listActionInfo.add(new ActionNxResubmit(NwConstants.L3_FIB_TABLE));
386         instructionInfo.add(new InstructionApplyActions(listActionInfo));
387
388         String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, routerId) + "INBOUND";
389         addFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef, NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef,
390             NwConstants.COOKIE_SNAT_TABLE, matches, instructionInfo);
391     }
392
393     protected void removeNaptPfibEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
394         long routerId) {
395         LOG.info("installNaptPfibEntry : called for dpnId {} and routerId {} ", dpnId, routerId);
396         String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, routerId) + "INBOUND";
397         removeFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef);
398     }
399 }