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.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
17 import org.opendaylight.genius.infra.Datastore.Configuration;
18 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
19 import org.opendaylight.genius.infra.TypedWriteTransaction;
20 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
21 import org.opendaylight.genius.mdsalutil.ActionInfo;
22 import org.opendaylight.genius.mdsalutil.BucketInfo;
23 import org.opendaylight.genius.mdsalutil.GroupEntity;
24 import org.opendaylight.genius.mdsalutil.InstructionInfo;
25 import org.opendaylight.genius.mdsalutil.MDSALUtil;
26 import org.opendaylight.genius.mdsalutil.MatchInfo;
27 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
28 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
29 import org.opendaylight.genius.mdsalutil.NwConstants;
30 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
31 import org.opendaylight.genius.mdsalutil.actions.ActionNxConntrack;
32 import org.opendaylight.genius.mdsalutil.actions.ActionNxConntrack.NxCtAction;
33 import org.opendaylight.genius.mdsalutil.actions.ActionNxLoadInPort;
34 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
35 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldMeta;
36 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldTunnelId;
37 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
38 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
39 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
40 import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Destination;
41 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
42 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
43 import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchCtState;
44 import org.opendaylight.netvirt.elanmanager.api.IElanService;
45 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
46 import org.opendaylight.netvirt.natservice.ha.NatDataUtil;
47 import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.types.rev160517.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 DataTreeEventCallbackRegistrar eventCallbacks) {
76 super(dataBroker, mdsalManager, itmManager, idManager, naptSwitchSelector, odlInterfaceRpcService,
77 interfaceManager, vpnFootprintService, fibManager, natDataUtil, eventCallbacks);
78 this.externalRouterListener = externalRouterListener;
79 this.elanManager = elanManager;
83 public boolean addSnatAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
84 BigInteger primarySwitchId) {
85 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
86 LOG.debug("VxlanGreConntrackBasedSnatService: handleSnatAllSwitch ProviderTypes {}", extNwProviderType);
87 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
88 LOG.debug("handleSnatAllSwitch : Skip FLAT/VLAN provider networks.");
91 return super.addSnatAllSwitch(confTx, routers, primarySwitchId);
95 public boolean removeSnatAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
96 BigInteger primarySwitchId) {
97 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
98 LOG.debug("VxlanGreConntrackBasedSnatService: handleSnatAllSwitch ProviderTypes {}", extNwProviderType);
99 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
100 LOG.debug("handleSnatAllSwitch : Skip FLAT/VLAN provider networks.");
103 return super.removeSnatAllSwitch(confTx, routers, primarySwitchId);
107 public boolean addSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
108 BigInteger primarySwitchId, BigInteger dpnId) {
109 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
110 LOG.debug("VxlanGreConntrackBasedSnatService: handleSnat ProviderTypes {}", extNwProviderType);
111 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
112 LOG.debug("handleSnat : Skip FLAT/VLAN provider networks.");
115 return super.addSnat(confTx, routers, primarySwitchId, dpnId);
119 public boolean removeSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
120 BigInteger primarySwitchId, BigInteger dpnId) {
121 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
122 LOG.debug("VxlanGreConntrackBasedSnatService: handleSnat ProviderTypes {}", extNwProviderType);
123 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
124 LOG.debug("handleSnat : Skip FLAT/VLAN provider networks.");
127 return super.removeSnat(confTx, routers, primarySwitchId, dpnId);
131 protected void addSnatSpecificEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
134 LOG.info("installSnatSpecificEntriesForNaptSwitch for router {}",
135 routers.getRouterName());
136 String routerName = routers.getRouterName();
137 Long routerId = NatUtil.getVpnId(dataBroker, routerName);
138 int elanId = NatUtil.getElanInstanceByName(routers.getNetworkId().getValue(), dataBroker)
139 .getElanTag().intValue();
140 /* Install Outbound NAT entries */
142 addSnatMissEntryForPrimrySwch(confTx, dpnId, routerId, elanId);
143 addTerminatingServiceTblEntryForVxlanGre(confTx, dpnId, routerName, routerId, elanId);
144 //Long extNetVpnId = NatUtil.getNetworkVpnIdFromRouterId(dataBroker, routerId);
145 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, routers.getNetworkId());
146 if (vpnUuid == null) {
147 LOG.error("installSnatSpecificEntriesForNaptSwitch: Unable to retrieve external vpn_id for "
148 + "external network {} with routerId {}", routers.getNetworkId(), routerId);
151 Long extNetVpnId = NatUtil.getVpnId(dataBroker, vpnUuid.getValue());
152 LOG.info("installSnatSpecificEntriesForNaptSwitch: external network vpn_id {} for router {}",
153 extNetVpnId, routers.getRouterName());
154 List<ExternalIps> externalIps = routers.getExternalIps();
155 addOutboundTblTrackEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId);
156 addOutboundTblEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId, externalIps, elanId);
157 addNaptPfibFlowForVxlanGre(confTx, routers, dpnId, extNetVpnId);
158 addNaptPfibEntry(confTx, dpnId, routerId);
160 //Install Inbound NAT entries
161 addInboundEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId, externalIps, elanId);
162 if (externalIps.isEmpty()) {
163 LOG.error("installSnatSpecificEntriesForNaptSwitch: No externalIP present for router {}",
167 //The logic now handle only one external IP per router, others if present will be ignored.
168 String externalIp = NatUtil.validateAndAddNetworkMask(externalIps.get(0).getIpAddress());
169 externalRouterListener.handleSnatReverseTraffic(confTx, dpnId, routers, routerId, routerName, externalIp);
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(), confTx);
213 protected void addOutboundTblTrackEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
214 Long routerId, Long extNetVpnId) {
215 LOG.info("createOutboundTblTrackEntryForVxlanGre: Install Outbound tracking table flow on dpId {} for "
216 + "routerId {}", dpnId, routerId);
217 List<MatchInfoBase> matches = new ArrayList<>();
218 matches.add(MatchEthernetType.IPV4);
219 matches.add(new NxMatchCtState(SNAT_CT_STATE, SNAT_CT_STATE_MASK));
220 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
222 ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
223 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil.getVpnIdMetadata(extNetVpnId));
224 listActionInfo.add(actionSetFieldMeta);
225 ArrayList<InstructionInfo> instructionInfo = new ArrayList<>();
226 listActionInfo.add(new ActionNxResubmit(NwConstants.NAPT_PFIB_TABLE));
227 instructionInfo.add(new InstructionApplyActions(listActionInfo));
229 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId) + "trkest";
230 addFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY, flowRef,
231 NwConstants.COOKIE_SNAT_TABLE, matches, instructionInfo);
235 protected void removeOutboundTblTrackEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx,
236 BigInteger dpnId, Long routerId) {
237 LOG.info("createOutboundTblTrackEntryForVxlanGre: Install Outbound tracking table flow on dpId {} for "
238 + "routerId {}", dpnId, routerId);
240 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId) + "trkest";
241 removeFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
245 protected void addOutboundTblEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
246 long routerId, Long extNetVpnId, List<ExternalIps> externalIps, int elanId) {
247 LOG.info("createOutboundTblEntryForVxlanGre: Install Outbound table flow on dpId {} for routerId {}", dpnId,
249 List<MatchInfoBase> matches = new ArrayList<>();
250 matches.add(MatchEthernetType.IPV4);
251 matches.add(new NxMatchCtState(TRACKED_NEW_CT_STATE, TRACKED_NEW_CT_MASK));
252 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
253 if (externalIps.isEmpty()) {
254 LOG.error("createOutboundTblEntryForVxlanGre: No externalIP present for routerId {}",
258 //The logic now handle only one external IP per router, others if present will be ignored.
259 String externalIp = externalIps.get(0).getIpAddress();
260 List<ActionInfo> actionsInfos = new ArrayList<>();
261 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
262 .getVpnIdMetadata(extNetVpnId));
263 actionsInfos.add(actionSetFieldMeta);
264 List<ActionNxConntrack.NxCtAction> ctActionsListCommit = new ArrayList<>();
265 int rangePresent = NxActionNatRangePresent.NXNATRANGEIPV4MIN.getIntValue();
266 int flags = NxActionNatFlags.NXNATFSRC.getIntValue();
267 ActionNxConntrack.NxCtAction nxCtActionCommit = new ActionNxConntrack.NxNat(0, flags, rangePresent,
268 new IpPrefixOrAddress(externalIp.toCharArray()).getIpAddress(),
270 ctActionsListCommit.add(nxCtActionCommit);
271 int ctCommitFlag = 1;
272 ActionNxConntrack actionNxConntrackSubmit = new ActionNxConntrack(ctCommitFlag, 0, elanId,
273 NwConstants.NAPT_PFIB_TABLE, ctActionsListCommit);
274 actionsInfos.add(actionNxConntrackSubmit);
275 List<InstructionInfo> instructions = new ArrayList<>();
276 instructions.add(new InstructionApplyActions(actionsInfos));
277 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
278 addFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef, NatConstants.SNAT_NEW_FLOW_PRIORITY,
279 flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
282 protected void removeOutboundTblEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
283 long routerId, List<ExternalIps> externalIps) {
284 LOG.info("createOutboundTblEntryForVxlanGre: Install Outbound table flow on dpId {} for routerId {}", dpnId,
286 if (externalIps.isEmpty()) {
287 LOG.error("createOutboundTblEntryForVxlanGre: No externalIP present for routerId {}",
291 //The logic now handle only one external IP per router, others if present will be ignored.
292 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
293 removeFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
296 protected void addNaptPfibFlowForVxlanGre(TypedWriteTransaction<Configuration> confTx, Routers routers,
297 BigInteger dpnId, Long extNetVpnId) {
298 LOG.info("installNaptPfibFlowForVxlanGre: Install Napt preFibFlow on dpId {} with matching extNetVpnId {} "
299 + "for router {}", dpnId, extNetVpnId, routers.getRouterName());
300 List<MatchInfoBase> matches = new ArrayList<>();
301 matches.add(MatchEthernetType.IPV4);
302 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNetVpnId),
303 MetaDataUtil.METADATA_MASK_VRFID));
304 ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
305 ArrayList<InstructionInfo> instructions = new ArrayList<>();
306 listActionInfo.add(new ActionNxLoadInPort(BigInteger.ZERO));
307 listActionInfo.add(new ActionNxResubmit(NwConstants.L3_FIB_TABLE));
308 instructions.add(new InstructionApplyActions(listActionInfo));
309 String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, extNetVpnId);
310 addFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY,
311 flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
314 protected void removeNaptPfibFlowForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
315 BigInteger dpnId, Long extNetVpnId) {
316 LOG.info("installNaptPfibFlowForVxlanGre: Install Napt preFibFlow on dpId {} with matching extNetVpnId {} "
317 + "for router {}", dpnId, extNetVpnId, routers.getRouterName());
318 String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, extNetVpnId);
319 removeFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef);
322 protected void addInboundEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
323 long routerId, Long extNeVpnId, List<ExternalIps> externalIps, int elanId) {
324 LOG.info("installInboundEntryForVxlanGre: Install Inbound table entry on dpId {} for routerId {}",
326 List<MatchInfoBase> matches = new ArrayList<>();
327 matches.add(MatchEthernetType.IPV4);
328 if (externalIps.isEmpty()) {
329 LOG.error("installInboundEntryForVxlanGre : createInboundTblEntry no externalIP present for routerId {}",
333 String externalIp = externalIps.get(0).getIpAddress();
334 matches.add(new MatchIpv4Destination(externalIp,"32"));
335 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNeVpnId), MetaDataUtil.METADATA_MASK_VRFID));
336 List<ActionInfo> actionsInfos = new ArrayList<>();
337 List<ActionNxConntrack.NxCtAction> ctActionsList = new ArrayList<>();
338 ActionNxConntrack.NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
339 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
340 .getVpnIdMetadata(routerId));
341 actionsInfos.add(actionSetFieldMeta);
342 ctActionsList.add(nxCtAction);
343 ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
344 .NAPT_PFIB_TABLE,ctActionsList);
346 actionsInfos.add(actionNxConntrack);
347 List<InstructionInfo> instructions = new ArrayList<>();
348 instructions.add(new InstructionApplyActions(actionsInfos));
349 String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
350 addFlow(confTx, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY, flowRef,
351 NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
354 protected void removeInboundEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
355 long routerId, List<ExternalIps> externalIps) {
356 LOG.info("removeInboundEntryForVxlanGre: remove Inbound table entry on dpId {} for routerId {}",
358 if (externalIps.isEmpty()) {
359 LOG.error("removeInboundEntryForVxlanGre : createInboundTblEntry no externalIP present for routerId {}",
364 String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
365 removeFlow(confTx, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef);
368 protected void addTerminatingServiceTblEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx,
369 BigInteger dpnId, String routerName, Long routerId, int elanId) {
370 LOG.info("installTerminatingServiceTblEntryForVxlanGre : creating entry for"
371 + "Terminating Service Table for switch {}, routerId {}", dpnId, routerId);
372 List<MatchInfo> matches = new ArrayList<>();
373 matches.add(MatchEthernetType.IPV4);
375 BigInteger tunnelId = BigInteger.valueOf(routerId);
376 if (elanManager.isOpenStackVniSemanticsEnforced()) {
377 tunnelId = NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId);
379 matches.add(new MatchTunnelId(tunnelId));
381 List<ActionInfo> actionsInfos = new ArrayList<>();
382 List<NxCtAction> ctActionsList = new ArrayList<>();
383 NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
384 ctActionsList.add(nxCtAction);
385 ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
386 .OUTBOUND_NAPT_TABLE,ctActionsList);
387 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
388 .getVpnIdMetadata(routerId.longValue()));
389 actionsInfos.add(actionSetFieldMeta);
390 actionsInfos.add(actionNxConntrack);
391 List<InstructionInfo> instructions = new ArrayList<>();
392 instructions.add(new InstructionApplyActions(actionsInfos));
393 String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId.longValue());
394 addFlow(confTx, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY,
395 flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
399 protected void removeTerminatingServiceTblEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx,
400 BigInteger dpnId, Long routerId) {
401 LOG.info("removeTerminatingServiceTblEntryForVxlanGre : removing entry for"
402 + "Terminating Service Table for switch {}, routerId {}", dpnId, routerId);
404 String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId.longValue());
405 removeFlow(confTx, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef);
410 protected void addSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId, Long routerId,
411 String routerName, BigInteger primarySwitchId) {
412 LOG.debug("installSnatMissEntry : Installing SNAT miss entry in switch {}", dpnId);
413 List<ActionInfo> listActionInfoPrimary = new ArrayList<>();
414 String ifNamePrimary = getTunnelInterfaceName(dpnId, primarySwitchId);
415 List<BucketInfo> listBucketInfo = new ArrayList<>();
416 if (ifNamePrimary != null) {
417 LOG.debug("installSnatMissEntry : On Non- Napt switch , Primary Tunnel interface is {}", ifNamePrimary);
418 listActionInfoPrimary = NatUtil.getEgressActionsForInterface(odlInterfaceRpcService, itmManager,
419 interfaceManager, ifNamePrimary, routerId, true);
421 BucketInfo bucketPrimary = new BucketInfo(listActionInfoPrimary);
422 listBucketInfo.add(0, bucketPrimary);
423 LOG.debug("installSnatMissEntry : installSnatMissEntry called for dpnId {} with primaryBucket {} ", dpnId,
424 listBucketInfo.get(0));
425 // Install the select group
426 long groupId = createGroupId(getGroupIdKey(routerName));
427 GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName, GroupTypes.GroupAll,
429 LOG.debug("installSnatMissEntry : installing the SNAT to NAPT GroupEntity:{}", groupEntity);
430 mdsalManager.addGroup(confTx, groupEntity);
431 // Install miss entry pointing to group
432 LOG.debug("installSnatMissEntry : buildSnatFlowEntity is called for dpId {}, routerName {} and groupId {}",
433 dpnId, routerName, groupId);
434 List<MatchInfo> matches = new ArrayList<>();
435 matches.add(new MatchEthernetType(0x0800L));
436 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
438 List<ActionInfo> actionsInfo = new ArrayList<>();
440 BigInteger tunnelId = BigInteger.valueOf(routerId);
441 if (elanManager.isOpenStackVniSemanticsEnforced()) {
442 tunnelId = NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId);
445 actionsInfo.add(new ActionSetFieldTunnelId(tunnelId));
446 LOG.debug("AbstractSnatService : Setting the tunnel to the list of action infos {}", actionsInfo);
447 actionsInfo.add(new ActionGroup(groupId));
448 List<InstructionInfo> instructions = new ArrayList<>();
449 instructions.add(new InstructionApplyActions(actionsInfo));
450 String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
451 addFlow(confTx, dpnId, NwConstants.PSNAT_TABLE, flowRef, NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef,
452 NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
456 protected void removeSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
457 Long routerId, String routerName) {
458 LOG.debug("installSnatMissEntry : Removing SNAT miss entry in switch {}", dpnId);
460 String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
461 removeFlow(confTx, dpnId, NwConstants.PSNAT_TABLE, flowRef);