2 * Copyright © 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.netvirt.natservice.internal;
10 import java.math.BigInteger;
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.List;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
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.BucketInfo;
22 import org.opendaylight.genius.mdsalutil.GroupEntity;
23 import org.opendaylight.genius.mdsalutil.InstructionInfo;
24 import org.opendaylight.genius.mdsalutil.MDSALUtil;
25 import org.opendaylight.genius.mdsalutil.MatchInfo;
26 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
27 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
28 import org.opendaylight.genius.mdsalutil.NwConstants;
29 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
30 import org.opendaylight.genius.mdsalutil.actions.ActionNxConntrack;
31 import org.opendaylight.genius.mdsalutil.actions.ActionNxConntrack.NxCtAction;
32 import org.opendaylight.genius.mdsalutil.actions.ActionNxLoadInPort;
33 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
34 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldMeta;
35 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldTunnelId;
36 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
37 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
38 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
39 import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Destination;
40 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
41 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
42 import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchCtState;
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.IpPrefixOrAddressBuilder;
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;
61 public class VxlanGreConntrackBasedSnatService extends ConntrackBasedSnatService {
63 private static final Logger LOG = LoggerFactory.getLogger(VxlanGreConntrackBasedSnatService.class);
64 private final ExternalRoutersListener externalRouterListener;
65 private final IElanService elanManager;
67 public VxlanGreConntrackBasedSnatService(DataBroker dataBroker, IMdsalApiManager mdsalManager,
68 ItmRpcService itmManager, OdlInterfaceRpcService odlInterfaceRpcService,
69 IdManagerService idManager, NAPTSwitchSelector naptSwitchSelector,
70 ExternalRoutersListener externalRouterListener, IElanService elanManager,
71 IInterfaceManager interfaceManager,
72 IVpnFootprintService vpnFootprintService,
73 IFibManager fibManager, NatDataUtil natDataUtil,
74 DataTreeEventCallbackRegistrar eventCallbacks) {
75 super(dataBroker, mdsalManager, itmManager, idManager, naptSwitchSelector, odlInterfaceRpcService,
76 interfaceManager, vpnFootprintService, fibManager, natDataUtil, eventCallbacks);
77 this.externalRouterListener = externalRouterListener;
78 this.elanManager = elanManager;
82 public boolean addSnatAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
83 BigInteger primarySwitchId) {
84 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, 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.");
90 return super.addSnatAllSwitch(confTx, routers, primarySwitchId);
94 public boolean removeSnatAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
95 BigInteger primarySwitchId) {
96 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
97 LOG.debug("VxlanGreConntrackBasedSnatService: handleSnatAllSwitch ProviderTypes {}", extNwProviderType);
98 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
99 LOG.debug("handleSnatAllSwitch : Skip FLAT/VLAN provider networks.");
102 return super.removeSnatAllSwitch(confTx, routers, primarySwitchId);
106 public boolean addSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
107 BigInteger primarySwitchId, BigInteger dpnId) {
108 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
109 LOG.debug("VxlanGreConntrackBasedSnatService: handleSnat ProviderTypes {}", extNwProviderType);
110 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
111 LOG.debug("handleSnat : Skip FLAT/VLAN provider networks.");
114 return super.addSnat(confTx, routers, primarySwitchId, dpnId);
118 public boolean removeSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
119 BigInteger primarySwitchId, BigInteger dpnId) {
120 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
121 LOG.debug("VxlanGreConntrackBasedSnatService: handleSnat ProviderTypes {}", extNwProviderType);
122 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
123 LOG.debug("handleSnat : Skip FLAT/VLAN provider networks.");
126 return super.removeSnat(confTx, routers, primarySwitchId, dpnId);
130 protected void addSnatSpecificEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
133 LOG.info("installSnatSpecificEntriesForNaptSwitch for router {}",
134 routers.getRouterName());
135 String routerName = routers.getRouterName();
136 Long routerId = NatUtil.getVpnId(dataBroker, routerName);
137 int elanId = NatUtil.getElanInstanceByName(routers.getNetworkId().getValue(), dataBroker)
138 .getElanTag().intValue();
139 /* Install Outbound NAT entries */
141 addSnatMissEntryForPrimrySwch(confTx, dpnId, routerId, elanId);
142 addTerminatingServiceTblEntryForVxlanGre(confTx, dpnId, routerName, routerId, elanId);
143 //Long extNetVpnId = NatUtil.getNetworkVpnIdFromRouterId(dataBroker, routerId);
144 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, routers.getNetworkId());
145 if (vpnUuid == null) {
146 LOG.error("installSnatSpecificEntriesForNaptSwitch: Unable to retrieve external vpn_id for "
147 + "external network {} with routerId {}", routers.getNetworkId(), routerId);
150 Long extNetVpnId = NatUtil.getVpnId(dataBroker, vpnUuid.getValue());
151 LOG.info("installSnatSpecificEntriesForNaptSwitch: external network vpn_id {} for router {}",
152 extNetVpnId, routers.getRouterName());
153 List<ExternalIps> externalIps = routers.getExternalIps();
154 addOutboundTblTrackEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId);
155 addOutboundTblEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId, externalIps, elanId);
156 addNaptPfibFlowForVxlanGre(confTx, routers, dpnId, extNetVpnId);
157 addNaptPfibEntry(confTx, dpnId, routerId);
159 //Install Inbound NAT entries
160 addInboundEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId, externalIps, elanId);
161 if (externalIps.isEmpty()) {
162 LOG.error("installSnatSpecificEntriesForNaptSwitch: No externalIP present for router {}",
166 //The logic now handle only one external IP per router, others if present will be ignored.
167 String externalIp = NatUtil.validateAndAddNetworkMask(externalIps.get(0).getIpAddress());
168 externalRouterListener.handleSnatReverseTraffic(confTx, dpnId, routers, routerId, routerName, externalIp);
172 protected void removeSnatSpecificEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
173 Routers routers, BigInteger dpnId) {
175 LOG.info("installSnatSpecificEntriesForNaptSwitch for router {}",
176 routers.getRouterName());
177 String routerName = routers.getRouterName();
178 Long routerId = NatUtil.getVpnId(dataBroker, routerName);
180 /* Remove Outbound NAT entries */
181 removeSnatMissEntryForPrimrySwch(confTx, dpnId, routerId);
182 removeTerminatingServiceTblEntryForVxlanGre(confTx, dpnId, routerId);
183 //Long extNetVpnId = NatUtil.getNetworkVpnIdFromRouterId(dataBroker, routerId);
184 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, routers.getNetworkId());
185 if (vpnUuid == null) {
186 LOG.error("installSnatSpecificEntriesForNaptSwitch: Unable to retrieve external vpn_id for "
187 + "external network {} with routerId {}", routers.getNetworkId(), routerId);
190 Long extNetVpnId = NatUtil.getVpnId(dataBroker, vpnUuid.getValue());
191 LOG.info("installSnatSpecificEntriesForNaptSwitch: external network vpn_id {} for router {}",
192 extNetVpnId, routers.getRouterName());
193 List<ExternalIps> externalIps = routers.getExternalIps();
194 removeOutboundTblTrackEntryForVxlanGre(confTx, dpnId, routerId);
195 removeOutboundTblEntryForVxlanGre(confTx, dpnId, routerId, externalIps);
196 removeNaptPfibFlowForVxlanGre(confTx, routers, dpnId, extNetVpnId);
197 removeNaptPfibEntry(confTx, dpnId, routerId);
199 //Install Inbound NAT entries
200 removeInboundEntryForVxlanGre(confTx, dpnId, routerId, externalIps);
201 if (externalIps.isEmpty()) {
202 LOG.error("installSnatSpecificEntriesForNaptSwitch: No externalIP present for router {}",
206 //The logic now handle only one external IP per router, others if present will be ignored.
207 String externalIp = NatUtil.validateAndAddNetworkMask(externalIps.get(0).getIpAddress());
208 externalRouterListener.clearFibTsAndReverseTraffic(dpnId, routerId, routers.getNetworkId(),
209 Collections.singletonList(externalIp), null, routers.getExtGwMacAddress(), confTx);
212 protected void addOutboundTblTrackEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
213 Long routerId, Long extNetVpnId) {
214 LOG.info("createOutboundTblTrackEntryForVxlanGre: Install Outbound tracking table flow on dpId {} for "
215 + "routerId {}", dpnId, routerId);
216 List<MatchInfoBase> matches = new ArrayList<>();
217 matches.add(MatchEthernetType.IPV4);
218 matches.add(new NxMatchCtState(SNAT_CT_STATE, SNAT_CT_STATE_MASK));
219 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
221 ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
222 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil.getVpnIdMetadata(extNetVpnId));
223 listActionInfo.add(actionSetFieldMeta);
224 ArrayList<InstructionInfo> instructionInfo = new ArrayList<>();
225 listActionInfo.add(new ActionNxResubmit(NwConstants.NAPT_PFIB_TABLE));
226 instructionInfo.add(new InstructionApplyActions(listActionInfo));
228 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId) + "trkest";
229 addFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY, flowRef,
230 NwConstants.COOKIE_SNAT_TABLE, matches, instructionInfo);
234 protected void removeOutboundTblTrackEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx,
235 BigInteger dpnId, Long routerId) {
236 LOG.info("createOutboundTblTrackEntryForVxlanGre: Install Outbound tracking table flow on dpId {} for "
237 + "routerId {}", dpnId, routerId);
239 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId) + "trkest";
240 removeFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
244 protected void addOutboundTblEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
245 long routerId, Long extNetVpnId, List<ExternalIps> externalIps, int elanId) {
246 LOG.info("createOutboundTblEntryForVxlanGre: Install Outbound table flow on dpId {} for routerId {}", dpnId,
248 List<MatchInfoBase> matches = new ArrayList<>();
249 matches.add(MatchEthernetType.IPV4);
250 matches.add(new NxMatchCtState(TRACKED_NEW_CT_STATE, TRACKED_NEW_CT_MASK));
251 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
252 if (externalIps.isEmpty()) {
253 LOG.error("createOutboundTblEntryForVxlanGre: No externalIP present for routerId {}",
257 //The logic now handle only one external IP per router, others if present will be ignored.
258 String externalIp = externalIps.get(0).getIpAddress();
259 List<ActionInfo> actionsInfos = new ArrayList<>();
260 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
261 .getVpnIdMetadata(extNetVpnId));
262 actionsInfos.add(actionSetFieldMeta);
263 List<ActionNxConntrack.NxCtAction> ctActionsListCommit = new ArrayList<>();
264 int rangePresent = NxActionNatRangePresent.NXNATRANGEIPV4MIN.getIntValue();
265 int flags = NxActionNatFlags.NXNATFSRC.getIntValue();
266 ActionNxConntrack.NxCtAction nxCtActionCommit = new ActionNxConntrack.NxNat(0, flags, rangePresent,
267 IpPrefixOrAddressBuilder.getDefaultInstance(externalIp).getIpAddress(), null,0, 0);
268 ctActionsListCommit.add(nxCtActionCommit);
269 int ctCommitFlag = 1;
270 ActionNxConntrack actionNxConntrackSubmit = new ActionNxConntrack(ctCommitFlag, 0, elanId,
271 NwConstants.NAPT_PFIB_TABLE, ctActionsListCommit);
272 actionsInfos.add(actionNxConntrackSubmit);
273 List<InstructionInfo> instructions = new ArrayList<>();
274 instructions.add(new InstructionApplyActions(actionsInfos));
275 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
276 addFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef, NatConstants.SNAT_NEW_FLOW_PRIORITY,
277 flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
280 protected void removeOutboundTblEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
281 long routerId, List<ExternalIps> externalIps) {
282 LOG.info("createOutboundTblEntryForVxlanGre: Install Outbound table flow on dpId {} for routerId {}", dpnId,
284 if (externalIps.isEmpty()) {
285 LOG.error("createOutboundTblEntryForVxlanGre: No externalIP present for routerId {}",
289 //The logic now handle only one external IP per router, others if present will be ignored.
290 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
291 removeFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
294 protected void addNaptPfibFlowForVxlanGre(TypedWriteTransaction<Configuration> confTx, Routers routers,
295 BigInteger dpnId, Long extNetVpnId) {
296 LOG.info("installNaptPfibFlowForVxlanGre: Install Napt preFibFlow on dpId {} with matching extNetVpnId {} "
297 + "for router {}", dpnId, extNetVpnId, routers.getRouterName());
298 List<MatchInfoBase> matches = new ArrayList<>();
299 matches.add(MatchEthernetType.IPV4);
300 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNetVpnId),
301 MetaDataUtil.METADATA_MASK_VRFID));
302 ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
303 ArrayList<InstructionInfo> instructions = new ArrayList<>();
304 listActionInfo.add(new ActionNxLoadInPort(BigInteger.ZERO));
305 listActionInfo.add(new ActionNxResubmit(NwConstants.L3_FIB_TABLE));
306 instructions.add(new InstructionApplyActions(listActionInfo));
307 String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, extNetVpnId);
308 addFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY,
309 flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
312 protected void removeNaptPfibFlowForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
313 BigInteger dpnId, Long extNetVpnId) {
314 LOG.info("installNaptPfibFlowForVxlanGre: Install Napt preFibFlow on dpId {} with matching extNetVpnId {} "
315 + "for router {}", dpnId, extNetVpnId, routers.getRouterName());
316 String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, extNetVpnId);
317 removeFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef);
320 protected void addInboundEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
321 long routerId, Long extNeVpnId, List<ExternalIps> externalIps, int elanId) {
322 LOG.info("installInboundEntryForVxlanGre: Install Inbound table entry on dpId {} for routerId {}",
324 List<MatchInfoBase> matches = new ArrayList<>();
325 matches.add(MatchEthernetType.IPV4);
326 if (externalIps.isEmpty()) {
327 LOG.error("installInboundEntryForVxlanGre : createInboundTblEntry no externalIP present for routerId {}",
331 String externalIp = externalIps.get(0).getIpAddress();
332 matches.add(new MatchIpv4Destination(externalIp,"32"));
333 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNeVpnId), MetaDataUtil.METADATA_MASK_VRFID));
334 List<ActionInfo> actionsInfos = new ArrayList<>();
335 List<ActionNxConntrack.NxCtAction> ctActionsList = new ArrayList<>();
336 ActionNxConntrack.NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
337 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
338 .getVpnIdMetadata(routerId));
339 actionsInfos.add(actionSetFieldMeta);
340 ctActionsList.add(nxCtAction);
341 ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
342 .NAPT_PFIB_TABLE,ctActionsList);
344 actionsInfos.add(actionNxConntrack);
345 List<InstructionInfo> instructions = new ArrayList<>();
346 instructions.add(new InstructionApplyActions(actionsInfos));
347 String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
348 addFlow(confTx, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY, flowRef,
349 NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
352 protected void removeInboundEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
353 long routerId, List<ExternalIps> externalIps) {
354 LOG.info("removeInboundEntryForVxlanGre: remove Inbound table entry on dpId {} for routerId {}",
356 if (externalIps.isEmpty()) {
357 LOG.error("removeInboundEntryForVxlanGre : createInboundTblEntry no externalIP present for routerId {}",
362 String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
363 removeFlow(confTx, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef);
366 protected void addTerminatingServiceTblEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx,
367 BigInteger dpnId, String routerName, Long routerId, int elanId) {
368 LOG.info("installTerminatingServiceTblEntryForVxlanGre : creating entry for"
369 + "Terminating Service Table for switch {}, routerId {}", dpnId, routerId);
370 List<MatchInfo> matches = new ArrayList<>();
371 matches.add(MatchEthernetType.IPV4);
373 BigInteger tunnelId = BigInteger.valueOf(routerId);
374 if (elanManager.isOpenStackVniSemanticsEnforced()) {
375 tunnelId = NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId);
377 matches.add(new MatchTunnelId(tunnelId));
379 List<ActionInfo> actionsInfos = new ArrayList<>();
380 List<NxCtAction> ctActionsList = new ArrayList<>();
381 NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
382 ctActionsList.add(nxCtAction);
383 ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
384 .OUTBOUND_NAPT_TABLE,ctActionsList);
385 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
386 .getVpnIdMetadata(routerId.longValue()));
387 actionsInfos.add(actionSetFieldMeta);
388 actionsInfos.add(actionNxConntrack);
389 List<InstructionInfo> instructions = new ArrayList<>();
390 instructions.add(new InstructionApplyActions(actionsInfos));
391 String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId.longValue());
392 addFlow(confTx, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY,
393 flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
397 protected void removeTerminatingServiceTblEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx,
398 BigInteger dpnId, Long routerId) {
399 LOG.info("removeTerminatingServiceTblEntryForVxlanGre : removing entry for"
400 + "Terminating Service Table for switch {}, routerId {}", dpnId, routerId);
402 String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId.longValue());
403 removeFlow(confTx, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef);
408 protected void addSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId, Long routerId,
409 String routerName, BigInteger primarySwitchId) {
410 LOG.debug("installSnatMissEntry : Installing SNAT miss entry in switch {}", dpnId);
411 List<ActionInfo> listActionInfoPrimary = new ArrayList<>();
412 String ifNamePrimary = getTunnelInterfaceName(dpnId, primarySwitchId);
413 List<BucketInfo> listBucketInfo = new ArrayList<>();
414 if (ifNamePrimary != null) {
415 LOG.debug("installSnatMissEntry : On Non- Napt switch , Primary Tunnel interface is {}", ifNamePrimary);
416 listActionInfoPrimary = NatUtil.getEgressActionsForInterface(odlInterfaceRpcService, itmManager,
417 interfaceManager, ifNamePrimary, routerId, true);
419 BucketInfo bucketPrimary = new BucketInfo(listActionInfoPrimary);
420 listBucketInfo.add(0, bucketPrimary);
421 LOG.debug("installSnatMissEntry : installSnatMissEntry called for dpnId {} with primaryBucket {} ", dpnId,
422 listBucketInfo.get(0));
423 // Install the select group
424 long groupId = createGroupId(getGroupIdKey(routerName));
425 GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName, GroupTypes.GroupAll,
427 LOG.debug("installSnatMissEntry : installing the SNAT to NAPT GroupEntity:{}", groupEntity);
428 mdsalManager.addGroup(confTx, groupEntity);
429 // Install miss entry pointing to group
430 LOG.debug("installSnatMissEntry : buildSnatFlowEntity is called for dpId {}, routerName {} and groupId {}",
431 dpnId, routerName, groupId);
432 List<MatchInfo> matches = new ArrayList<>();
433 matches.add(new MatchEthernetType(0x0800L));
434 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
436 List<ActionInfo> actionsInfo = new ArrayList<>();
438 BigInteger tunnelId = BigInteger.valueOf(routerId);
439 if (elanManager.isOpenStackVniSemanticsEnforced()) {
440 tunnelId = NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId);
443 actionsInfo.add(new ActionSetFieldTunnelId(tunnelId));
444 LOG.debug("AbstractSnatService : Setting the tunnel to the list of action infos {}", actionsInfo);
445 actionsInfo.add(new ActionGroup(groupId));
446 List<InstructionInfo> instructions = new ArrayList<>();
447 instructions.add(new InstructionApplyActions(actionsInfo));
448 String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
449 addFlow(confTx, dpnId, NwConstants.PSNAT_TABLE, flowRef, NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef,
450 NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
454 protected void removeSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
455 Long routerId, String routerName) {
456 LOG.debug("installSnatMissEntry : Removing SNAT miss entry in switch {}", dpnId);
458 String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
459 removeFlow(confTx, dpnId, NwConstants.PSNAT_TABLE, flowRef);