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;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.genius.infra.Datastore.Configuration;
17 import org.opendaylight.genius.infra.TransactionAdapter;
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.IpPrefixOrAddress;
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;
62 public class VxlanGreConntrackBasedSnatService extends ConntrackBasedSnatService {
64 private static final Logger LOG = LoggerFactory.getLogger(VxlanGreConntrackBasedSnatService.class);
65 private final ExternalRoutersListener externalRouterListener;
66 private final IElanService elanManager;
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;
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(dpnId, routers, routerId, routerName, externalIp,
169 TransactionAdapter.toWriteTransaction(confTx));
173 protected void removeSnatSpecificEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
174 Routers routers, BigInteger dpnId) {
176 LOG.info("installSnatSpecificEntriesForNaptSwitch for router {}",
177 routers.getRouterName());
178 String routerName = routers.getRouterName();
179 Long routerId = NatUtil.getVpnId(dataBroker, routerName);
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);
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);
200 //Install Inbound NAT entries
201 removeInboundEntryForVxlanGre(confTx, dpnId, routerId, externalIps);
202 if (externalIps.isEmpty()) {
203 LOG.error("installSnatSpecificEntriesForNaptSwitch: No externalIP present for router {}",
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(),
211 TransactionAdapter.toWriteTransaction(confTx));
214 protected void addOutboundTblTrackEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
215 Long routerId, Long extNetVpnId) {
216 LOG.info("createOutboundTblTrackEntryForVxlanGre: Install Outbound tracking table flow on dpId {} for "
217 + "routerId {}", dpnId, routerId);
218 List<MatchInfoBase> matches = new ArrayList<>();
219 matches.add(MatchEthernetType.IPV4);
220 matches.add(new NxMatchCtState(SNAT_CT_STATE, SNAT_CT_STATE_MASK));
221 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
223 ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
224 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil.getVpnIdMetadata(extNetVpnId));
225 listActionInfo.add(actionSetFieldMeta);
226 ArrayList<InstructionInfo> instructionInfo = new ArrayList<>();
227 listActionInfo.add(new ActionNxResubmit(NwConstants.NAPT_PFIB_TABLE));
228 instructionInfo.add(new InstructionApplyActions(listActionInfo));
230 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId) + "trkest";
231 addFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY, flowRef,
232 NwConstants.COOKIE_SNAT_TABLE, matches, instructionInfo);
236 protected void removeOutboundTblTrackEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx,
237 BigInteger dpnId, Long routerId) {
238 LOG.info("createOutboundTblTrackEntryForVxlanGre: Install Outbound tracking table flow on dpId {} for "
239 + "routerId {}", dpnId, routerId);
241 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId) + "trkest";
242 removeFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
246 protected void addOutboundTblEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
247 long routerId, Long extNetVpnId, List<ExternalIps> externalIps, int elanId) {
248 LOG.info("createOutboundTblEntryForVxlanGre: Install Outbound table flow on dpId {} for routerId {}", dpnId,
250 List<MatchInfoBase> matches = new ArrayList<>();
251 matches.add(MatchEthernetType.IPV4);
252 matches.add(new NxMatchCtState(TRACKED_NEW_CT_STATE, TRACKED_NEW_CT_MASK));
253 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
254 if (externalIps.isEmpty()) {
255 LOG.error("createOutboundTblEntryForVxlanGre: No externalIP present for routerId {}",
259 //The logic now handle only one external IP per router, others if present will be ignored.
260 String externalIp = externalIps.get(0).getIpAddress();
261 List<ActionInfo> actionsInfos = new ArrayList<>();
262 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
263 .getVpnIdMetadata(extNetVpnId));
264 actionsInfos.add(actionSetFieldMeta);
265 List<ActionNxConntrack.NxCtAction> ctActionsListCommit = new ArrayList<>();
266 int rangePresent = NxActionNatRangePresent.NXNATRANGEIPV4MIN.getIntValue();
267 int flags = NxActionNatFlags.NXNATFSRC.getIntValue();
268 ActionNxConntrack.NxCtAction nxCtActionCommit = new ActionNxConntrack.NxNat(0, flags, rangePresent,
269 new IpPrefixOrAddress(externalIp.toCharArray()).getIpAddress(),
271 ctActionsListCommit.add(nxCtActionCommit);
272 int ctCommitFlag = 1;
273 ActionNxConntrack actionNxConntrackSubmit = new ActionNxConntrack(ctCommitFlag, 0, elanId,
274 NwConstants.NAPT_PFIB_TABLE, ctActionsListCommit);
275 actionsInfos.add(actionNxConntrackSubmit);
276 List<InstructionInfo> instructions = new ArrayList<>();
277 instructions.add(new InstructionApplyActions(actionsInfos));
278 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
279 addFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef, NatConstants.SNAT_NEW_FLOW_PRIORITY,
280 flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
283 protected void removeOutboundTblEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
284 long routerId, List<ExternalIps> externalIps) {
285 LOG.info("createOutboundTblEntryForVxlanGre: Install Outbound table flow on dpId {} for routerId {}", dpnId,
287 if (externalIps.isEmpty()) {
288 LOG.error("createOutboundTblEntryForVxlanGre: No externalIP present for routerId {}",
292 //The logic now handle only one external IP per router, others if present will be ignored.
293 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
294 removeFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
297 protected void addNaptPfibFlowForVxlanGre(TypedWriteTransaction<Configuration> confTx, Routers routers,
298 BigInteger dpnId, Long extNetVpnId) {
299 LOG.info("installNaptPfibFlowForVxlanGre: Install Napt preFibFlow on dpId {} with matching extNetVpnId {} "
300 + "for router {}", dpnId, extNetVpnId, routers.getRouterName());
301 List<MatchInfoBase> matches = new ArrayList<>();
302 matches.add(MatchEthernetType.IPV4);
303 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNetVpnId),
304 MetaDataUtil.METADATA_MASK_VRFID));
305 ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
306 ArrayList<InstructionInfo> instructions = new ArrayList<>();
307 listActionInfo.add(new ActionNxLoadInPort(BigInteger.ZERO));
308 listActionInfo.add(new ActionNxResubmit(NwConstants.L3_FIB_TABLE));
309 instructions.add(new InstructionApplyActions(listActionInfo));
310 String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, extNetVpnId);
311 addFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY,
312 flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
315 protected void removeNaptPfibFlowForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
316 BigInteger dpnId, Long extNetVpnId) {
317 LOG.info("installNaptPfibFlowForVxlanGre: Install Napt preFibFlow on dpId {} with matching extNetVpnId {} "
318 + "for router {}", dpnId, extNetVpnId, routers.getRouterName());
319 String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, extNetVpnId);
320 removeFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef);
323 protected void addInboundEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
324 long routerId, Long extNeVpnId, List<ExternalIps> externalIps, int elanId) {
325 LOG.info("installInboundEntryForVxlanGre: Install Inbound table entry on dpId {} for routerId {}",
327 List<MatchInfoBase> matches = new ArrayList<>();
328 matches.add(MatchEthernetType.IPV4);
329 if (externalIps.isEmpty()) {
330 LOG.error("installInboundEntryForVxlanGre : createInboundTblEntry no externalIP present for routerId {}",
334 String externalIp = externalIps.get(0).getIpAddress();
335 matches.add(new MatchIpv4Destination(externalIp,"32"));
336 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNeVpnId), MetaDataUtil.METADATA_MASK_VRFID));
337 List<ActionInfo> actionsInfos = new ArrayList<>();
338 List<ActionNxConntrack.NxCtAction> ctActionsList = new ArrayList<>();
339 ActionNxConntrack.NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
340 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
341 .getVpnIdMetadata(routerId));
342 actionsInfos.add(actionSetFieldMeta);
343 ctActionsList.add(nxCtAction);
344 ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
345 .NAPT_PFIB_TABLE,ctActionsList);
347 actionsInfos.add(actionNxConntrack);
348 List<InstructionInfo> instructions = new ArrayList<>();
349 instructions.add(new InstructionApplyActions(actionsInfos));
350 String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
351 addFlow(confTx, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY, flowRef,
352 NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
355 protected void removeInboundEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
356 long routerId, List<ExternalIps> externalIps) {
357 LOG.info("removeInboundEntryForVxlanGre: remove Inbound table entry on dpId {} for routerId {}",
359 if (externalIps.isEmpty()) {
360 LOG.error("removeInboundEntryForVxlanGre : createInboundTblEntry no externalIP present for routerId {}",
365 String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
366 removeFlow(confTx, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef);
369 protected void addTerminatingServiceTblEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx,
370 BigInteger dpnId, String routerName, Long routerId, int elanId) {
371 LOG.info("installTerminatingServiceTblEntryForVxlanGre : creating entry for"
372 + "Terminating Service Table for switch {}, routerId {}", dpnId, routerId);
373 List<MatchInfo> matches = new ArrayList<>();
374 matches.add(MatchEthernetType.IPV4);
376 BigInteger tunnelId = BigInteger.valueOf(routerId);
377 if (elanManager.isOpenStackVniSemanticsEnforced()) {
378 tunnelId = NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId);
380 matches.add(new MatchTunnelId(tunnelId));
382 List<ActionInfo> actionsInfos = new ArrayList<>();
383 List<NxCtAction> ctActionsList = new ArrayList<>();
384 NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
385 ctActionsList.add(nxCtAction);
386 ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
387 .OUTBOUND_NAPT_TABLE,ctActionsList);
388 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
389 .getVpnIdMetadata(routerId.longValue()));
390 actionsInfos.add(actionSetFieldMeta);
391 actionsInfos.add(actionNxConntrack);
392 List<InstructionInfo> instructions = new ArrayList<>();
393 instructions.add(new InstructionApplyActions(actionsInfos));
394 String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId.longValue());
395 addFlow(confTx, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY,
396 flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
400 protected void removeTerminatingServiceTblEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx,
401 BigInteger dpnId, Long routerId) {
402 LOG.info("removeTerminatingServiceTblEntryForVxlanGre : removing entry for"
403 + "Terminating Service Table for switch {}, routerId {}", dpnId, routerId);
405 String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId.longValue());
406 removeFlow(confTx, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef);
411 protected void addSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId, Long routerId,
412 String routerName, BigInteger primarySwitchId) {
413 LOG.debug("installSnatMissEntry : Installing SNAT miss entry in switch {}", dpnId);
414 List<ActionInfo> listActionInfoPrimary = new ArrayList<>();
415 String ifNamePrimary = getTunnelInterfaceName(dpnId, primarySwitchId);
416 List<BucketInfo> listBucketInfo = new ArrayList<>();
417 if (ifNamePrimary != null) {
418 LOG.debug("installSnatMissEntry : On Non- Napt switch , Primary Tunnel interface is {}", ifNamePrimary);
419 listActionInfoPrimary = NatUtil.getEgressActionsForInterface(odlInterfaceRpcService, itmManager,
420 interfaceManager, ifNamePrimary, routerId, true);
422 BucketInfo bucketPrimary = new BucketInfo(listActionInfoPrimary);
423 listBucketInfo.add(0, bucketPrimary);
424 LOG.debug("installSnatMissEntry : installSnatMissEntry called for dpnId {} with primaryBucket {} ", dpnId,
425 listBucketInfo.get(0));
426 // Install the select group
427 long groupId = createGroupId(getGroupIdKey(routerName));
428 GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName, GroupTypes.GroupAll,
430 LOG.debug("installSnatMissEntry : installing the SNAT to NAPT GroupEntity:{}", groupEntity);
431 mdsalManager.addGroup(confTx, groupEntity);
432 // Install miss entry pointing to group
433 LOG.debug("installSnatMissEntry : buildSnatFlowEntity is called for dpId {}, routerName {} and groupId {}",
434 dpnId, routerName, groupId);
435 List<MatchInfo> matches = new ArrayList<>();
436 matches.add(new MatchEthernetType(0x0800L));
437 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
439 List<ActionInfo> actionsInfo = new ArrayList<>();
441 BigInteger tunnelId = BigInteger.valueOf(routerId);
442 if (elanManager.isOpenStackVniSemanticsEnforced()) {
443 tunnelId = NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId);
446 actionsInfo.add(new ActionSetFieldTunnelId(tunnelId));
447 LOG.debug("AbstractSnatService : Setting the tunnel to the list of action infos {}", actionsInfo);
448 actionsInfo.add(new ActionGroup(groupId));
449 List<InstructionInfo> instructions = new ArrayList<>();
450 instructions.add(new InstructionApplyActions(actionsInfo));
451 String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
452 addFlow(confTx, dpnId, NwConstants.PSNAT_TABLE, flowRef, NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef,
453 NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
457 protected void removeSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
458 Long routerId, String routerName) {
459 LOG.debug("installSnatMissEntry : Removing SNAT miss entry in switch {}", dpnId);
461 String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
462 removeFlow(confTx, dpnId, NwConstants.PSNAT_TABLE, flowRef);