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 java.util.concurrent.ExecutionException;
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.IpPrefixOrAddressBuilder;
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) throws ExecutionException, InterruptedException {
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) throws ExecutionException, InterruptedException {
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) throws ExecutionException, InterruptedException {
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) throws ExecutionException, InterruptedException {
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 IpPrefixOrAddressBuilder.getDefaultInstance(externalIp).getIpAddress(), null,0, 0);
269 ctActionsListCommit.add(nxCtActionCommit);
270 int ctCommitFlag = 1;
271 ActionNxConntrack actionNxConntrackSubmit = new ActionNxConntrack(ctCommitFlag, 0, elanId,
272 NwConstants.NAPT_PFIB_TABLE, ctActionsListCommit);
273 actionsInfos.add(actionNxConntrackSubmit);
274 List<InstructionInfo> instructions = new ArrayList<>();
275 instructions.add(new InstructionApplyActions(actionsInfos));
276 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
277 addFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef, NatConstants.SNAT_NEW_FLOW_PRIORITY,
278 flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
281 protected void removeOutboundTblEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
282 long routerId, List<ExternalIps> externalIps) throws ExecutionException, InterruptedException {
283 LOG.info("createOutboundTblEntryForVxlanGre: Install Outbound table flow on dpId {} for routerId {}", dpnId,
285 if (externalIps.isEmpty()) {
286 LOG.error("createOutboundTblEntryForVxlanGre: No externalIP present for routerId {}",
290 //The logic now handle only one external IP per router, others if present will be ignored.
291 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
292 removeFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
295 protected void addNaptPfibFlowForVxlanGre(TypedWriteTransaction<Configuration> confTx, Routers routers,
296 BigInteger dpnId, Long extNetVpnId) {
297 LOG.info("installNaptPfibFlowForVxlanGre: Install Napt preFibFlow on dpId {} with matching extNetVpnId {} "
298 + "for router {}", dpnId, extNetVpnId, routers.getRouterName());
299 List<MatchInfoBase> matches = new ArrayList<>();
300 matches.add(MatchEthernetType.IPV4);
301 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNetVpnId),
302 MetaDataUtil.METADATA_MASK_VRFID));
303 ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
304 ArrayList<InstructionInfo> instructions = new ArrayList<>();
305 listActionInfo.add(new ActionNxLoadInPort(BigInteger.ZERO));
306 listActionInfo.add(new ActionNxResubmit(NwConstants.L3_FIB_TABLE));
307 instructions.add(new InstructionApplyActions(listActionInfo));
308 String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, extNetVpnId);
309 addFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY,
310 flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
313 protected void removeNaptPfibFlowForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
314 BigInteger dpnId, Long extNetVpnId) throws ExecutionException, InterruptedException {
315 LOG.info("installNaptPfibFlowForVxlanGre: Install Napt preFibFlow on dpId {} with matching extNetVpnId {} "
316 + "for router {}", dpnId, extNetVpnId, routers.getRouterName());
317 String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, extNetVpnId);
318 removeFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef);
321 protected void addInboundEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
322 long routerId, Long extNeVpnId, List<ExternalIps> externalIps, int elanId) {
323 LOG.info("installInboundEntryForVxlanGre: Install Inbound table entry on dpId {} for routerId {}",
325 List<MatchInfoBase> matches = new ArrayList<>();
326 matches.add(MatchEthernetType.IPV4);
327 if (externalIps.isEmpty()) {
328 LOG.error("installInboundEntryForVxlanGre : createInboundTblEntry no externalIP present for routerId {}",
332 String externalIp = externalIps.get(0).getIpAddress();
333 matches.add(new MatchIpv4Destination(externalIp,"32"));
334 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNeVpnId), MetaDataUtil.METADATA_MASK_VRFID));
335 List<ActionInfo> actionsInfos = new ArrayList<>();
336 List<ActionNxConntrack.NxCtAction> ctActionsList = new ArrayList<>();
337 ActionNxConntrack.NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
338 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
339 .getVpnIdMetadata(routerId));
340 actionsInfos.add(actionSetFieldMeta);
341 ctActionsList.add(nxCtAction);
342 ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
343 .NAPT_PFIB_TABLE,ctActionsList);
345 actionsInfos.add(actionNxConntrack);
346 List<InstructionInfo> instructions = new ArrayList<>();
347 instructions.add(new InstructionApplyActions(actionsInfos));
348 String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
349 addFlow(confTx, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY, flowRef,
350 NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
353 protected void removeInboundEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
354 long routerId, List<ExternalIps> externalIps) throws ExecutionException, InterruptedException {
355 LOG.info("removeInboundEntryForVxlanGre: remove Inbound table entry on dpId {} for routerId {}",
357 if (externalIps.isEmpty()) {
358 LOG.error("removeInboundEntryForVxlanGre : createInboundTblEntry no externalIP present for routerId {}",
363 String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
364 removeFlow(confTx, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef);
367 protected void addTerminatingServiceTblEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx,
368 BigInteger dpnId, String routerName, Long routerId, int elanId) {
369 LOG.info("installTerminatingServiceTblEntryForVxlanGre : creating entry for"
370 + "Terminating Service Table for switch {}, routerId {}", dpnId, routerId);
371 List<MatchInfo> matches = new ArrayList<>();
372 matches.add(MatchEthernetType.IPV4);
374 BigInteger tunnelId = BigInteger.valueOf(routerId);
375 if (elanManager.isOpenStackVniSemanticsEnforced()) {
376 tunnelId = NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId);
378 matches.add(new MatchTunnelId(tunnelId));
380 List<ActionInfo> actionsInfos = new ArrayList<>();
381 List<NxCtAction> ctActionsList = new ArrayList<>();
382 NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
383 ctActionsList.add(nxCtAction);
384 ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
385 .OUTBOUND_NAPT_TABLE,ctActionsList);
386 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
387 .getVpnIdMetadata(routerId.longValue()));
388 actionsInfos.add(actionSetFieldMeta);
389 actionsInfos.add(actionNxConntrack);
390 List<InstructionInfo> instructions = new ArrayList<>();
391 instructions.add(new InstructionApplyActions(actionsInfos));
392 String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId.longValue());
393 addFlow(confTx, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY,
394 flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
398 protected void removeTerminatingServiceTblEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx,
399 BigInteger dpnId, Long routerId) throws ExecutionException, InterruptedException {
400 LOG.info("removeTerminatingServiceTblEntryForVxlanGre : removing entry for"
401 + "Terminating Service Table for switch {}, routerId {}", dpnId, routerId);
403 String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId.longValue());
404 removeFlow(confTx, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef);
409 protected void addSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId, Long routerId,
410 String routerName, BigInteger primarySwitchId) {
411 LOG.debug("installSnatMissEntry : Installing SNAT miss entry in switch {}", dpnId);
412 List<ActionInfo> listActionInfoPrimary = new ArrayList<>();
413 String ifNamePrimary = getTunnelInterfaceName(dpnId, primarySwitchId);
414 List<BucketInfo> listBucketInfo = new ArrayList<>();
415 if (ifNamePrimary != null) {
416 LOG.debug("installSnatMissEntry : On Non- Napt switch , Primary Tunnel interface is {}", ifNamePrimary);
417 listActionInfoPrimary = NatUtil.getEgressActionsForInterface(odlInterfaceRpcService, itmManager,
418 interfaceManager, ifNamePrimary, routerId, true);
420 BucketInfo bucketPrimary = new BucketInfo(listActionInfoPrimary);
421 listBucketInfo.add(0, bucketPrimary);
422 LOG.debug("installSnatMissEntry : installSnatMissEntry called for dpnId {} with primaryBucket {} ", dpnId,
423 listBucketInfo.get(0));
424 // Install the select group
425 long groupId = createGroupId(getGroupIdKey(routerName));
426 GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName, GroupTypes.GroupAll,
428 LOG.debug("installSnatMissEntry : installing the SNAT to NAPT GroupEntity:{}", groupEntity);
429 mdsalManager.addGroup(confTx, groupEntity);
430 // Install miss entry pointing to group
431 LOG.debug("installSnatMissEntry : buildSnatFlowEntity is called for dpId {}, routerName {} and groupId {}",
432 dpnId, routerName, groupId);
433 List<MatchInfo> matches = new ArrayList<>();
434 matches.add(new MatchEthernetType(0x0800L));
435 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
437 List<ActionInfo> actionsInfo = new ArrayList<>();
439 BigInteger tunnelId = BigInteger.valueOf(routerId);
440 if (elanManager.isOpenStackVniSemanticsEnforced()) {
441 tunnelId = NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId);
444 actionsInfo.add(new ActionSetFieldTunnelId(tunnelId));
445 LOG.debug("AbstractSnatService : Setting the tunnel to the list of action infos {}", actionsInfo);
446 actionsInfo.add(new ActionGroup(groupId));
447 List<InstructionInfo> instructions = new ArrayList<>();
448 instructions.add(new InstructionApplyActions(actionsInfo));
449 String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
450 addFlow(confTx, dpnId, NwConstants.PSNAT_TABLE, flowRef, NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef,
451 NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
455 protected void removeSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
456 Long routerId, String routerName) throws ExecutionException, InterruptedException {
457 LOG.debug("installSnatMissEntry : Removing SNAT miss entry in switch {}", dpnId);
459 String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
460 removeFlow(confTx, dpnId, NwConstants.PSNAT_TABLE, flowRef);