Fixes stale fib flows for the g/w and PNF
[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
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
17 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
18 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
19 import org.opendaylight.genius.mdsalutil.ActionInfo;
20 import org.opendaylight.genius.mdsalutil.BucketInfo;
21 import org.opendaylight.genius.mdsalutil.GroupEntity;
22 import org.opendaylight.genius.mdsalutil.InstructionInfo;
23 import org.opendaylight.genius.mdsalutil.MDSALUtil;
24 import org.opendaylight.genius.mdsalutil.MatchInfo;
25 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
26 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
27 import org.opendaylight.genius.mdsalutil.NwConstants;
28 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
29 import org.opendaylight.genius.mdsalutil.actions.ActionNxConntrack;
30 import org.opendaylight.genius.mdsalutil.actions.ActionNxConntrack.NxCtAction;
31 import org.opendaylight.genius.mdsalutil.actions.ActionNxLoadInPort;
32 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
33 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldMeta;
34 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldTunnelId;
35 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
36 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
37 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
38 import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Destination;
39 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
40 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
41 import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchCtState;
42 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
43 import org.opendaylight.netvirt.elanmanager.api.IElanService;
44 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
45 import org.opendaylight.netvirt.natservice.ha.NatDataUtil;
46 import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.types.rev160517.IpPrefixOrAddress;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.NxActionNatFlags;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.NxActionNatRangePresent;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60
61 public class VxlanGreConntrackBasedSnatService extends ConntrackBasedSnatService {
62
63     private static final Logger LOG = LoggerFactory.getLogger(VxlanGreConntrackBasedSnatService.class);
64     private final ExternalRoutersListener externalRouterListener;
65     private final IElanService elanManager;
66     private final ManagedNewTransactionRunner txRunner;
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         super(dataBroker, mdsalManager, itmManager, idManager, naptSwitchSelector, odlInterfaceRpcService,
76                 interfaceManager, vpnFootprintService, fibManager, natDataUtil);
77         this.externalRouterListener = externalRouterListener;
78         this.elanManager = elanManager;
79         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
80     }
81
82     @Override
83     public boolean handleSnatAllSwitch(Routers routers, BigInteger primarySwitchId,  int addOrRemove) {
84         ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
85         LOG.debug("VxlanGreConntrackBasedSnatService: handleSnatAllSwitch ProviderTypes {}", extNwProviderType);
86         if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
87             LOG.debug("handleSnatAllSwitch : Skip FLAT/VLAN provider networks.");
88             return true;
89         }
90         return super.handleSnatAllSwitch(routers, primarySwitchId, addOrRemove);
91     }
92
93     @Override
94     public boolean handleSnat(Routers routers, BigInteger primarySwitchId, BigInteger dpnId,  int addOrRemove) {
95         ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
96         LOG.debug("VxlanGreConntrackBasedSnatService: handleSnat ProviderTypes {}", extNwProviderType);
97         if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
98             LOG.debug("handleSnat : Skip FLAT/VLAN provider networks.");
99             return true;
100         }
101         return super.handleSnat(routers, primarySwitchId, dpnId, addOrRemove);
102     }
103
104     @Override
105     protected void installSnatSpecificEntriesForNaptSwitch(Routers routers, BigInteger dpnId, int addOrRemove) {
106         LOG.info("installSnatSpecificEntriesForNaptSwitch for router {}",
107                 routers.getRouterName());
108         String routerName = routers.getRouterName();
109         Long routerId = NatUtil.getVpnId(dataBroker, routerName);
110         int elanId = NatUtil.getElanInstanceByName(routers.getNetworkId().getValue(), dataBroker)
111                 .getElanTag().intValue();
112         /* Install Outbound NAT entries */
113
114         installSnatMissEntryForPrimrySwch(dpnId, routerId, elanId, addOrRemove);
115         installTerminatingServiceTblEntryForVxlanGre(dpnId, routerName, routerId, elanId, addOrRemove);
116         //Long extNetVpnId = NatUtil.getNetworkVpnIdFromRouterId(dataBroker, routerId);
117         Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, routers.getNetworkId());
118         if (vpnUuid == null) {
119             LOG.error("installSnatSpecificEntriesForNaptSwitch: Unable to retrieve external vpn_id for "
120                     + "external network {} with routerId {}", routers.getNetworkId(), routerId);
121             return;
122         }
123         Long extNetVpnId = NatUtil.getVpnId(dataBroker, vpnUuid.getValue());
124         /*//Long extNetVpnId = NatUtil.getAssociatedVPN(dataBroker, routers.getNetworkId(), LOG);
125         if (extNetVpnId == NatConstants.INVALID_ID && addOrRemove == NwConstants.ADD_FLOW) {
126             LOG.error("installSnatSpecificEntriesForNaptSwitch: Unable to retrieve external vpn_id for "
127                     + "external network {} with routerId {}", routers.getNetworkId(), routerId);
128             return;
129         }*/
130         LOG.info("installSnatSpecificEntriesForNaptSwitch: external network vpn_id {} for router {}",
131                 extNetVpnId, routers.getRouterName());
132         List<ExternalIps> externalIps = routers.getExternalIps();
133         createOutboundTblTrackEntryForVxlanGre(dpnId, routerId, extNetVpnId, addOrRemove);
134         createOutboundTblEntryForVxlanGre(dpnId, routerId, extNetVpnId, externalIps, elanId, addOrRemove);
135         installNaptPfibFlowForVxlanGre(routers, dpnId, extNetVpnId, addOrRemove);
136         installNaptPfibEntry(dpnId, routerId, addOrRemove);
137
138         //Install Inbound NAT entries
139         installInboundEntryForVxlanGre(dpnId, routerId, extNetVpnId, externalIps, elanId, addOrRemove);
140         if (externalIps.isEmpty()) {
141             LOG.error("installSnatSpecificEntriesForNaptSwitch: No externalIP present for router {}",
142                     routerName);
143             return;
144         }
145         //The logic now handle only one external IP per router, others if present will be ignored.
146         String externalIp = NatUtil.validateAndAddNetworkMask(externalIps.get(0).getIpAddress());
147         ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
148             if (addOrRemove == NwConstants.ADD_FLOW) {
149                 externalRouterListener.handleSnatReverseTraffic(dpnId, routers, routerId, routerName, externalIp, tx);
150             } else {
151                 externalRouterListener.clearFibTsAndReverseTraffic(dpnId, routerId, routers.getNetworkId(),
152                         Collections.singletonList(externalIp), null, routers.getExtGwMacAddress(), tx);
153             }
154         }), LOG, "Error installing SNAT-specific entries for NAPT switch");
155     }
156
157     protected void createOutboundTblTrackEntryForVxlanGre(BigInteger dpnId, Long routerId, Long extNetVpnId,
158                                                int addOrRemove) {
159         LOG.info("createOutboundTblTrackEntryForVxlanGre: Install Outbound tracking table flow on dpId {} for "
160                 + "routerId {}", dpnId, routerId);
161         List<MatchInfoBase> matches = new ArrayList<>();
162         matches.add(MatchEthernetType.IPV4);
163         matches.add(new NxMatchCtState(SNAT_CT_STATE, SNAT_CT_STATE_MASK));
164         matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
165
166         ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
167         if (addOrRemove == NwConstants.ADD_FLOW) {
168             ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
169                     .getVpnIdMetadata(extNetVpnId));
170             listActionInfo.add(actionSetFieldMeta);
171         }
172         ArrayList<InstructionInfo> instructionInfo = new ArrayList<>();
173         listActionInfo.add(new ActionNxResubmit(NwConstants.NAPT_PFIB_TABLE));
174         instructionInfo.add(new InstructionApplyActions(listActionInfo));
175
176         String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
177         flowRef += "trkest";
178         syncFlow(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY, flowRef,
179                 NwConstants.COOKIE_SNAT_TABLE, matches, instructionInfo, addOrRemove);
180
181     }
182
183     protected void createOutboundTblEntryForVxlanGre(BigInteger dpnId, long routerId, Long extNetVpnId,
184                                                      List<ExternalIps> externalIps, int elanId, int addOrRemove) {
185         LOG.info("createOutboundTblEntryForVxlanGre: Install Outbound table flow on dpId {} for routerId {}", dpnId,
186                 routerId);
187         List<MatchInfoBase> matches = new ArrayList<>();
188         matches.add(MatchEthernetType.IPV4);
189         matches.add(new NxMatchCtState(TRACKED_NEW_CT_STATE, TRACKED_NEW_CT_MASK));
190         matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
191         if (externalIps.isEmpty()) {
192             LOG.error("createOutboundTblEntryForVxlanGre: No externalIP present for routerId {}",
193                     routerId);
194             return;
195         }
196         //The logic now handle only one external IP per router, others if present will be ignored.
197         String externalIp = externalIps.get(0).getIpAddress();
198         List<ActionInfo> actionsInfos = new ArrayList<>();
199         if (addOrRemove == NwConstants.ADD_FLOW) {
200             ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
201                     .getVpnIdMetadata(extNetVpnId));
202             actionsInfos.add(actionSetFieldMeta);
203         }
204         List<ActionNxConntrack.NxCtAction> ctActionsListCommit = new ArrayList<>();
205         int rangePresent = NxActionNatRangePresent.NXNATRANGEIPV4MIN.getIntValue();
206         int flags = NxActionNatFlags.NXNATFSRC.getIntValue();
207         ActionNxConntrack.NxCtAction nxCtActionCommit = new ActionNxConntrack.NxNat(0, flags, rangePresent,
208                 new IpPrefixOrAddress(externalIp.toCharArray()).getIpAddress(),
209                 null,0, 0);
210         ctActionsListCommit.add(nxCtActionCommit);
211         int ctCommitFlag = 1;
212         ActionNxConntrack actionNxConntrackSubmit = new ActionNxConntrack(ctCommitFlag, 0, elanId,
213                 NwConstants.NAPT_PFIB_TABLE, ctActionsListCommit);
214         actionsInfos.add(actionNxConntrackSubmit);
215         List<InstructionInfo> instructions = new ArrayList<>();
216         instructions.add(new InstructionApplyActions(actionsInfos));
217         String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
218         syncFlow(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef,  NatConstants.SNAT_NEW_FLOW_PRIORITY,
219                 flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
220     }
221
222     protected void installNaptPfibFlowForVxlanGre(Routers routers, BigInteger dpnId, Long extNetVpnId,
223                                                   int addOrRemove) {
224         LOG.info("installNaptPfibFlowForVxlanGre: Install Napt preFibFlow on dpId {} with matching extNetVpnId {} "
225                 + "for router {}", dpnId, extNetVpnId, routers.getRouterName());
226         List<MatchInfoBase> matches = new ArrayList<>();
227         matches.add(MatchEthernetType.IPV4);
228         if (addOrRemove == NwConstants.ADD_FLOW) {
229             matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNetVpnId),
230                     MetaDataUtil.METADATA_MASK_VRFID));
231         }
232         ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
233         ArrayList<InstructionInfo> instructions = new ArrayList<>();
234         listActionInfo.add(new ActionNxLoadInPort(BigInteger.ZERO));
235         listActionInfo.add(new ActionNxResubmit(NwConstants.L3_FIB_TABLE));
236         instructions.add(new InstructionApplyActions(listActionInfo));
237         String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, extNetVpnId);
238         syncFlow(dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY,
239                 flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
240     }
241
242     protected void installInboundEntryForVxlanGre(BigInteger dpnId, long routerId, Long extNeVpnId,
243                                                   List<ExternalIps> externalIps, int elanId, int addOrRemove) {
244         LOG.info("installInboundEntryForVxlanGre:  Install Inbound table entry on dpId {} for routerId {}",
245                 dpnId, routerId);
246         List<MatchInfoBase> matches = new ArrayList<>();
247         matches.add(MatchEthernetType.IPV4);
248         if (externalIps.isEmpty()) {
249             LOG.error("installInboundEntryForVxlanGre : createInboundTblEntry no externalIP present for routerId {}",
250                     routerId);
251             return;
252         }
253         String externalIp = externalIps.get(0).getIpAddress();
254         matches.add(new MatchIpv4Destination(externalIp,"32"));
255         if (addOrRemove == NwConstants.ADD_FLOW) {
256             matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNeVpnId),
257                     MetaDataUtil.METADATA_MASK_VRFID));
258         }
259         List<ActionInfo> actionsInfos = new ArrayList<>();
260         List<ActionNxConntrack.NxCtAction> ctActionsList = new ArrayList<>();
261         ActionNxConntrack.NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
262         ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
263                 .getVpnIdMetadata(routerId));
264         actionsInfos.add(actionSetFieldMeta);
265         ctActionsList.add(nxCtAction);
266         ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
267                 .NAPT_PFIB_TABLE,ctActionsList);
268
269         actionsInfos.add(actionNxConntrack);
270         List<InstructionInfo> instructions = new ArrayList<>();
271         instructions.add(new InstructionApplyActions(actionsInfos));
272         String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
273         syncFlow(dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY, flowRef,
274                 NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
275     }
276
277     protected void installTerminatingServiceTblEntryForVxlanGre(BigInteger dpnId, String routerName,
278             Long  routerId, int elanId, int addOrRemove) {
279         LOG.info("installTerminatingServiceTblEntryForVxlanGre : creating entry for"
280                 + "Terminating Service Table for switch {}, routerId {}", dpnId, routerId);
281         List<MatchInfo> matches = new ArrayList<>();
282         matches.add(MatchEthernetType.IPV4);
283
284         BigInteger tunnelId = BigInteger.valueOf(routerId);
285         if (elanManager.isOpenStackVniSemanticsEnforced()) {
286             tunnelId = NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId);
287         }
288         matches.add(new MatchTunnelId(tunnelId));
289
290         List<ActionInfo> actionsInfos = new ArrayList<>();
291         List<NxCtAction> ctActionsList = new ArrayList<>();
292         NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
293         ctActionsList.add(nxCtAction);
294         ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
295                 .OUTBOUND_NAPT_TABLE,ctActionsList);
296         ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
297                 .getVpnIdMetadata(routerId.longValue()));
298         actionsInfos.add(actionSetFieldMeta);
299         actionsInfos.add(actionNxConntrack);
300         List<InstructionInfo> instructions = new ArrayList<>();
301         instructions.add(new InstructionApplyActions(actionsInfos));
302         String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId.longValue());
303         syncFlow(dpnId,  NwConstants.INTERNAL_TUNNEL_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY, flowRef,
304                  NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
305
306     }
307
308     protected void installSnatMissEntry(BigInteger dpnId, Long routerId, String routerName, BigInteger primarySwitchId,
309             int addOrRemove) {
310         LOG.debug("installSnatMissEntry : Installing SNAT miss entry in switch {}", dpnId);
311         List<ActionInfo> listActionInfoPrimary = new ArrayList<>();
312         String ifNamePrimary = getTunnelInterfaceName(dpnId, primarySwitchId);
313         List<BucketInfo> listBucketInfo = new ArrayList<>();
314         if (ifNamePrimary != null) {
315             LOG.debug("installSnatMissEntry : On Non- Napt switch , Primary Tunnel interface is {}", ifNamePrimary);
316             listActionInfoPrimary = NatUtil.getEgressActionsForInterface(odlInterfaceRpcService, itmManager,
317                     interfaceManager, ifNamePrimary, routerId, true);
318         }
319         BucketInfo bucketPrimary = new BucketInfo(listActionInfoPrimary);
320         listBucketInfo.add(0, bucketPrimary);
321         LOG.debug("installSnatMissEntry : installSnatMissEntry called for dpnId {} with primaryBucket {} ", dpnId,
322                 listBucketInfo.get(0));
323         // Install the select group
324         long groupId = createGroupId(getGroupIdKey(routerName));
325         GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName, GroupTypes.GroupAll,
326                 listBucketInfo);
327         LOG.debug("installSnatMissEntry : installing the SNAT to NAPT GroupEntity:{}", groupEntity);
328         mdsalManager.installGroup(groupEntity);
329         // Install miss entry pointing to group
330         LOG.debug("installSnatMissEntry : buildSnatFlowEntity is called for dpId {}, routerName {} and groupId {}",
331                 dpnId, routerName, groupId);
332         List<MatchInfo> matches = new ArrayList<>();
333         matches.add(new MatchEthernetType(0x0800L));
334         matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
335
336         List<ActionInfo> actionsInfo = new ArrayList<>();
337
338         BigInteger tunnelId = BigInteger.valueOf(routerId);
339         if (elanManager.isOpenStackVniSemanticsEnforced()) {
340             tunnelId = NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId);
341         }
342
343         actionsInfo.add(new ActionSetFieldTunnelId(tunnelId));
344         LOG.debug("AbstractSnatService : Setting the tunnel to the list of action infos {}", actionsInfo);
345         actionsInfo.add(new ActionGroup(groupId));
346         List<InstructionInfo> instructions = new ArrayList<>();
347         instructions.add(new InstructionApplyActions(actionsInfo));
348         String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
349         syncFlow(dpnId, NwConstants.PSNAT_TABLE, flowRef,  NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef,
350                 NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
351     }
352
353 }