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;
67 private final NatOverVxlanUtil natOverVxlanUtil;
69 public VxlanGreConntrackBasedSnatService(DataBroker dataBroker, IMdsalApiManager mdsalManager,
70 ItmRpcService itmManager, OdlInterfaceRpcService odlInterfaceRpcService,
71 IdManagerService idManager, NAPTSwitchSelector naptSwitchSelector,
72 ExternalRoutersListener externalRouterListener, IElanService elanManager,
73 IInterfaceManager interfaceManager,
74 IVpnFootprintService vpnFootprintService,
75 IFibManager fibManager, NatDataUtil natDataUtil,
76 DataTreeEventCallbackRegistrar eventCallbacks,
77 NatOverVxlanUtil natOverVxlanUtil) {
78 super(dataBroker, mdsalManager, itmManager, idManager, naptSwitchSelector, odlInterfaceRpcService,
79 interfaceManager, vpnFootprintService, fibManager, natDataUtil, eventCallbacks);
80 this.externalRouterListener = externalRouterListener;
81 this.elanManager = elanManager;
82 this.natOverVxlanUtil = natOverVxlanUtil;
86 public boolean addSnatAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
87 BigInteger primarySwitchId) {
88 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
89 LOG.debug("VxlanGreConntrackBasedSnatService: handleSnatAllSwitch ProviderTypes {}", extNwProviderType);
90 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
91 LOG.debug("handleSnatAllSwitch : Skip FLAT/VLAN provider networks.");
94 return super.addSnatAllSwitch(confTx, routers, primarySwitchId);
98 public boolean removeSnatAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
99 BigInteger primarySwitchId) throws ExecutionException, InterruptedException {
100 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
101 LOG.debug("VxlanGreConntrackBasedSnatService: handleSnatAllSwitch ProviderTypes {}", extNwProviderType);
102 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
103 LOG.debug("handleSnatAllSwitch : Skip FLAT/VLAN provider networks.");
106 return super.removeSnatAllSwitch(confTx, routers, primarySwitchId);
109 public boolean addCentralizedRouterAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
110 BigInteger primarySwitchId) {
111 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
112 LOG.debug("VxlanGreConntrackBasedSnatService: handleCentralizedRouterAllSwitch ProviderTypes {}",
114 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
115 LOG.debug("handleCentralizedRouterAllSwitch : Skip FLAT/VLAN provider networks.");
118 return super.addCentralizedRouterAllSwitch(confTx, routers, primarySwitchId);
121 public boolean removeCentralizedRouterAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
122 BigInteger primarySwitchId) throws ExecutionException, InterruptedException {
123 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
124 LOG.debug("VxlanGreConntrackBasedSnatService: handleCentralizedRouterAllSwitch ProviderTypes {}",
126 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
127 LOG.debug("handleCentralizedRouterAllSwitch : Skip FLAT/VLAN provider networks.");
130 return super.removeCentralizedRouterAllSwitch(confTx, routers, primarySwitchId);
133 public boolean addCentralizedRouter(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
134 BigInteger primarySwitchId, BigInteger dpnId) {
135 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
136 LOG.debug("VxlanGreConntrackBasedSnatService: handleCentralizedRouter ProviderTypes {}", extNwProviderType);
137 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
138 LOG.debug("handleCentralizedRouter : Skip FLAT/VLAN provider networks.");
141 return super.addCentralizedRouter(confTx, routers, primarySwitchId, dpnId);
144 public boolean removeCentralizedRouter(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
145 BigInteger primarySwitchId, BigInteger dpnId) throws ExecutionException, InterruptedException {
146 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
147 LOG.debug("VxlanGreConntrackBasedSnatService: handleCentralizedRouter ProviderTypes {}", extNwProviderType);
148 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
149 LOG.debug("handleCentralizedRouter : Skip FLAT/VLAN provider networks.");
152 return super.removeCentralizedRouter(confTx, routers, primarySwitchId, dpnId);
156 public boolean addSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
157 BigInteger primarySwitchId, BigInteger dpnId) {
158 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
159 LOG.debug("VxlanGreConntrackBasedSnatService: handleSnat ProviderTypes {}", extNwProviderType);
160 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
161 LOG.debug("handleSnat : Skip FLAT/VLAN provider networks.");
164 return super.addSnat(confTx, routers, primarySwitchId, dpnId);
168 public boolean removeSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
169 BigInteger primarySwitchId, BigInteger dpnId) throws ExecutionException, InterruptedException {
170 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
171 LOG.debug("VxlanGreConntrackBasedSnatService: handleSnat ProviderTypes {}", extNwProviderType);
172 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
173 LOG.debug("handleSnat : Skip FLAT/VLAN provider networks.");
176 return super.removeSnat(confTx, routers, primarySwitchId, dpnId);
180 protected void addSnatSpecificEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
183 LOG.info("installSnatSpecificEntriesForNaptSwitch for router {}",
184 routers.getRouterName());
185 String routerName = routers.getRouterName();
186 Long routerId = NatUtil.getVpnId(dataBroker, routerName);
187 int elanId = NatUtil.getElanInstanceByName(routers.getNetworkId().getValue(), dataBroker)
188 .getElanTag().intValue();
189 /* Install Outbound NAT entries */
191 addSnatMissEntryForPrimrySwch(confTx, dpnId, routerId, elanId);
192 addTerminatingServiceTblEntryForVxlanGre(confTx, dpnId, routerName, routerId, elanId);
193 //Long extNetVpnId = NatUtil.getNetworkVpnIdFromRouterId(dataBroker, routerId);
194 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, routers.getNetworkId());
195 if (vpnUuid == null) {
196 LOG.error("installSnatSpecificEntriesForNaptSwitch: Unable to retrieve external vpn_id for "
197 + "external network {} with routerId {}", routers.getNetworkId(), routerId);
200 Long extNetVpnId = NatUtil.getVpnId(dataBroker, vpnUuid.getValue());
201 LOG.info("installSnatSpecificEntriesForNaptSwitch: external network vpn_id {} for router {}",
202 extNetVpnId, routers.getRouterName());
203 List<ExternalIps> externalIps = routers.getExternalIps();
204 addOutboundTblTrackEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId);
205 addOutboundTblEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId, externalIps, elanId);
206 addNaptPfibFlowForVxlanGre(confTx, routers, dpnId, extNetVpnId);
207 addNaptPfibEntry(confTx, dpnId, routerId);
209 //Install Inbound NAT entries
210 addInboundEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId, externalIps, elanId);
211 if (externalIps.isEmpty()) {
212 LOG.error("installSnatSpecificEntriesForNaptSwitch: No externalIP present for router {}",
216 //The logic now handle only one external IP per router, others if present will be ignored.
217 String externalIp = NatUtil.validateAndAddNetworkMask(externalIps.get(0).getIpAddress());
218 externalRouterListener.handleSnatReverseTraffic(confTx, dpnId, routers, routerId, routerName, externalIp);
222 protected void removeSnatSpecificEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
223 Routers routers, BigInteger dpnId) throws ExecutionException, InterruptedException {
225 LOG.info("installSnatSpecificEntriesForNaptSwitch for router {}",
226 routers.getRouterName());
227 String routerName = routers.getRouterName();
228 Long routerId = NatUtil.getVpnId(dataBroker, routerName);
230 /* Remove Outbound NAT entries */
231 removeSnatMissEntryForPrimrySwch(confTx, dpnId, routerId);
232 removeTerminatingServiceTblEntryForVxlanGre(confTx, dpnId, routerId);
233 //Long extNetVpnId = NatUtil.getNetworkVpnIdFromRouterId(dataBroker, routerId);
234 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, routers.getNetworkId());
235 if (vpnUuid == null) {
236 LOG.error("installSnatSpecificEntriesForNaptSwitch: Unable to retrieve external vpn_id for "
237 + "external network {} with routerId {}", routers.getNetworkId(), routerId);
240 Long extNetVpnId = NatUtil.getVpnId(dataBroker, vpnUuid.getValue());
241 LOG.info("installSnatSpecificEntriesForNaptSwitch: external network vpn_id {} for router {}",
242 extNetVpnId, routers.getRouterName());
243 List<ExternalIps> externalIps = routers.getExternalIps();
244 removeOutboundTblTrackEntryForVxlanGre(confTx, dpnId, routerId);
245 removeOutboundTblEntryForVxlanGre(confTx, dpnId, routerId, externalIps);
246 removeNaptPfibFlowForVxlanGre(confTx, routers, dpnId, extNetVpnId);
247 removeNaptPfibEntry(confTx, dpnId, routerId);
249 //Install Inbound NAT entries
250 removeInboundEntryForVxlanGre(confTx, dpnId, routerId, externalIps);
251 if (externalIps.isEmpty()) {
252 LOG.error("installSnatSpecificEntriesForNaptSwitch: No externalIP present for router {}",
256 //The logic now handle only one external IP per router, others if present will be ignored.
257 String externalIp = NatUtil.validateAndAddNetworkMask(externalIps.get(0).getIpAddress());
258 externalRouterListener.clearFibTsAndReverseTraffic(dpnId, routerId, routers.getNetworkId(),
259 Collections.singletonList(externalIp), null, routers.getExtGwMacAddress(), confTx);
262 protected void addOutboundTblTrackEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
263 Long routerId, Long extNetVpnId) {
264 LOG.info("createOutboundTblTrackEntryForVxlanGre: Install Outbound tracking table flow on dpId {} for "
265 + "routerId {}", dpnId, routerId);
266 List<MatchInfoBase> matches = new ArrayList<>();
267 matches.add(MatchEthernetType.IPV4);
268 matches.add(new NxMatchCtState(SNAT_CT_STATE, SNAT_CT_STATE_MASK));
269 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
271 ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
272 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil.getVpnIdMetadata(extNetVpnId));
273 listActionInfo.add(actionSetFieldMeta);
274 ArrayList<InstructionInfo> instructionInfo = new ArrayList<>();
275 listActionInfo.add(new ActionNxResubmit(NwConstants.NAPT_PFIB_TABLE));
276 instructionInfo.add(new InstructionApplyActions(listActionInfo));
278 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId) + "trkest";
279 addFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY, flowRef,
280 NwConstants.COOKIE_SNAT_TABLE, matches, instructionInfo);
284 protected void removeOutboundTblTrackEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx,
285 BigInteger dpnId, Long routerId) throws ExecutionException, InterruptedException {
286 LOG.info("createOutboundTblTrackEntryForVxlanGre: Install Outbound tracking table flow on dpId {} for "
287 + "routerId {}", dpnId, routerId);
289 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId) + "trkest";
290 removeFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
294 protected void addOutboundTblEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
295 long routerId, Long extNetVpnId, List<ExternalIps> externalIps, int elanId) {
296 LOG.info("createOutboundTblEntryForVxlanGre: Install Outbound table flow on dpId {} for routerId {}", dpnId,
298 List<MatchInfoBase> matches = new ArrayList<>();
299 matches.add(MatchEthernetType.IPV4);
300 matches.add(new NxMatchCtState(TRACKED_NEW_CT_STATE, TRACKED_NEW_CT_MASK));
301 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
302 if (externalIps.isEmpty()) {
303 LOG.error("createOutboundTblEntryForVxlanGre: No externalIP present for routerId {}",
307 //The logic now handle only one external IP per router, others if present will be ignored.
308 String externalIp = externalIps.get(0).getIpAddress();
309 List<ActionInfo> actionsInfos = new ArrayList<>();
310 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
311 .getVpnIdMetadata(extNetVpnId));
312 actionsInfos.add(actionSetFieldMeta);
313 List<ActionNxConntrack.NxCtAction> ctActionsListCommit = new ArrayList<>();
314 int rangePresent = NxActionNatRangePresent.NXNATRANGEIPV4MIN.getIntValue();
315 int flags = NxActionNatFlags.NXNATFSRC.getIntValue();
316 ActionNxConntrack.NxCtAction nxCtActionCommit = new ActionNxConntrack.NxNat(0, flags, rangePresent,
317 IpPrefixOrAddressBuilder.getDefaultInstance(externalIp).getIpAddress(), null,0, 0);
318 ctActionsListCommit.add(nxCtActionCommit);
319 int ctCommitFlag = 1;
320 ActionNxConntrack actionNxConntrackSubmit = new ActionNxConntrack(ctCommitFlag, 0, elanId,
321 NwConstants.NAPT_PFIB_TABLE, ctActionsListCommit);
322 actionsInfos.add(actionNxConntrackSubmit);
323 List<InstructionInfo> instructions = new ArrayList<>();
324 instructions.add(new InstructionApplyActions(actionsInfos));
325 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
326 addFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef, NatConstants.SNAT_NEW_FLOW_PRIORITY,
327 flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
330 protected void removeOutboundTblEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
331 long routerId, List<ExternalIps> externalIps) throws ExecutionException, InterruptedException {
332 LOG.info("createOutboundTblEntryForVxlanGre: Install Outbound table flow on dpId {} for routerId {}", dpnId,
334 if (externalIps.isEmpty()) {
335 LOG.error("createOutboundTblEntryForVxlanGre: No externalIP present for routerId {}",
339 //The logic now handle only one external IP per router, others if present will be ignored.
340 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
341 removeFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
344 protected void addNaptPfibFlowForVxlanGre(TypedWriteTransaction<Configuration> confTx, Routers routers,
345 BigInteger dpnId, Long extNetVpnId) {
346 LOG.info("installNaptPfibFlowForVxlanGre: Install Napt preFibFlow on dpId {} with matching extNetVpnId {} "
347 + "for router {}", dpnId, extNetVpnId, routers.getRouterName());
348 List<MatchInfoBase> matches = new ArrayList<>();
349 matches.add(MatchEthernetType.IPV4);
350 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNetVpnId),
351 MetaDataUtil.METADATA_MASK_VRFID));
352 ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
353 ArrayList<InstructionInfo> instructions = new ArrayList<>();
354 listActionInfo.add(new ActionNxLoadInPort(BigInteger.ZERO));
355 listActionInfo.add(new ActionNxResubmit(NwConstants.L3_FIB_TABLE));
356 instructions.add(new InstructionApplyActions(listActionInfo));
357 String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, extNetVpnId);
358 addFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY,
359 flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
362 protected void removeNaptPfibFlowForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
363 BigInteger dpnId, Long extNetVpnId) throws ExecutionException, InterruptedException {
364 LOG.info("installNaptPfibFlowForVxlanGre: Install Napt preFibFlow on dpId {} with matching extNetVpnId {} "
365 + "for router {}", dpnId, extNetVpnId, routers.getRouterName());
366 String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, extNetVpnId);
367 removeFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef);
370 protected void addInboundEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
371 long routerId, Long extNeVpnId, List<ExternalIps> externalIps, int elanId) {
372 LOG.info("installInboundEntryForVxlanGre: Install Inbound table entry on dpId {} for routerId {}",
374 List<MatchInfoBase> matches = new ArrayList<>();
375 matches.add(MatchEthernetType.IPV4);
376 if (externalIps.isEmpty()) {
377 LOG.error("installInboundEntryForVxlanGre : createInboundTblEntry no externalIP present for routerId {}",
381 String externalIp = externalIps.get(0).getIpAddress();
382 matches.add(new MatchIpv4Destination(externalIp,"32"));
383 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNeVpnId), MetaDataUtil.METADATA_MASK_VRFID));
384 List<ActionInfo> actionsInfos = new ArrayList<>();
385 List<ActionNxConntrack.NxCtAction> ctActionsList = new ArrayList<>();
386 ActionNxConntrack.NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
387 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
388 .getVpnIdMetadata(routerId));
389 actionsInfos.add(actionSetFieldMeta);
390 ctActionsList.add(nxCtAction);
391 ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
392 .NAPT_PFIB_TABLE,ctActionsList);
394 actionsInfos.add(actionNxConntrack);
395 List<InstructionInfo> instructions = new ArrayList<>();
396 instructions.add(new InstructionApplyActions(actionsInfos));
397 String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
398 addFlow(confTx, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY, flowRef,
399 NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
402 protected void removeInboundEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
403 long routerId, List<ExternalIps> externalIps) throws ExecutionException, InterruptedException {
404 LOG.info("removeInboundEntryForVxlanGre: remove Inbound table entry on dpId {} for routerId {}",
406 if (externalIps.isEmpty()) {
407 LOG.error("removeInboundEntryForVxlanGre : createInboundTblEntry no externalIP present for routerId {}",
412 String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
413 removeFlow(confTx, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef);
416 protected void addTerminatingServiceTblEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx,
417 BigInteger dpnId, String routerName, Long routerId, int elanId) {
418 LOG.info("installTerminatingServiceTblEntryForVxlanGre : creating entry for"
419 + "Terminating Service Table for switch {}, routerId {}", dpnId, routerId);
420 List<MatchInfo> matches = new ArrayList<>();
421 matches.add(MatchEthernetType.IPV4);
423 BigInteger tunnelId = BigInteger.valueOf(routerId);
424 if (elanManager.isOpenStackVniSemanticsEnforced()) {
425 tunnelId = natOverVxlanUtil.getRouterVni(routerName, routerId);
427 matches.add(new MatchTunnelId(tunnelId));
429 List<ActionInfo> actionsInfos = new ArrayList<>();
430 List<NxCtAction> ctActionsList = new ArrayList<>();
431 NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
432 ctActionsList.add(nxCtAction);
433 ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
434 .OUTBOUND_NAPT_TABLE,ctActionsList);
435 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
436 .getVpnIdMetadata(routerId.longValue()));
437 actionsInfos.add(actionSetFieldMeta);
438 actionsInfos.add(actionNxConntrack);
439 List<InstructionInfo> instructions = new ArrayList<>();
440 instructions.add(new InstructionApplyActions(actionsInfos));
441 String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId.longValue());
442 addFlow(confTx, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY,
443 flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
447 protected void removeTerminatingServiceTblEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx,
448 BigInteger dpnId, Long routerId) throws ExecutionException, InterruptedException {
449 LOG.info("removeTerminatingServiceTblEntryForVxlanGre : removing entry for"
450 + "Terminating Service Table for switch {}, routerId {}", dpnId, routerId);
452 String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId.longValue());
453 removeFlow(confTx, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef);
458 protected void addSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId, Long routerId,
459 String routerName, BigInteger primarySwitchId) {
460 LOG.debug("installSnatMissEntry : Installing SNAT miss entry in switch {}", dpnId);
461 List<ActionInfo> listActionInfoPrimary = new ArrayList<>();
462 String ifNamePrimary = getTunnelInterfaceName(dpnId, primarySwitchId);
463 List<BucketInfo> listBucketInfo = new ArrayList<>();
464 if (ifNamePrimary != null) {
465 LOG.debug("installSnatMissEntry : On Non- Napt switch , Primary Tunnel interface is {}", ifNamePrimary);
466 listActionInfoPrimary = NatUtil.getEgressActionsForInterface(odlInterfaceRpcService, itmManager,
467 interfaceManager, ifNamePrimary, routerId, true);
469 BucketInfo bucketPrimary = new BucketInfo(listActionInfoPrimary);
470 listBucketInfo.add(0, bucketPrimary);
471 LOG.debug("installSnatMissEntry : installSnatMissEntry called for dpnId {} with primaryBucket {} ", dpnId,
472 listBucketInfo.get(0));
473 // Install the select group
474 long groupId = createGroupId(getGroupIdKey(routerName));
475 GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName, GroupTypes.GroupAll,
477 LOG.debug("installSnatMissEntry : installing the SNAT to NAPT GroupEntity:{}", groupEntity);
478 mdsalManager.addGroup(confTx, groupEntity);
479 // Install miss entry pointing to group
480 LOG.debug("installSnatMissEntry : buildSnatFlowEntity is called for dpId {}, routerName {} and groupId {}",
481 dpnId, routerName, groupId);
482 List<MatchInfo> matches = new ArrayList<>();
483 matches.add(new MatchEthernetType(0x0800L));
484 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
486 List<ActionInfo> actionsInfo = new ArrayList<>();
488 BigInteger tunnelId = BigInteger.valueOf(routerId);
489 if (elanManager.isOpenStackVniSemanticsEnforced()) {
490 tunnelId = natOverVxlanUtil.getRouterVni(routerName, routerId);
493 actionsInfo.add(new ActionSetFieldTunnelId(tunnelId));
494 LOG.debug("AbstractSnatService : Setting the tunnel to the list of action infos {}", actionsInfo);
495 actionsInfo.add(new ActionGroup(groupId));
496 List<InstructionInfo> instructions = new ArrayList<>();
497 instructions.add(new InstructionApplyActions(actionsInfo));
498 String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
499 addFlow(confTx, dpnId, NwConstants.PSNAT_TABLE, flowRef, NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef,
500 NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
504 protected void removeSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
505 Long routerId, String routerName) throws ExecutionException, InterruptedException {
506 LOG.debug("installSnatMissEntry : Removing SNAT miss entry in switch {}", dpnId);
508 String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
509 removeFlow(confTx, dpnId, NwConstants.PSNAT_TABLE, flowRef);