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);
106 public boolean addCentralizedRouterAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
107 BigInteger primarySwitchId) {
108 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
109 LOG.debug("VxlanGreConntrackBasedSnatService: handleCentralizedRouterAllSwitch ProviderTypes {}",
111 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
112 LOG.debug("handleCentralizedRouterAllSwitch : Skip FLAT/VLAN provider networks.");
115 return super.addCentralizedRouterAllSwitch(confTx, routers, primarySwitchId);
118 public boolean removeCentralizedRouterAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
119 BigInteger primarySwitchId) throws ExecutionException, InterruptedException {
120 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
121 LOG.debug("VxlanGreConntrackBasedSnatService: handleCentralizedRouterAllSwitch ProviderTypes {}",
123 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
124 LOG.debug("handleCentralizedRouterAllSwitch : Skip FLAT/VLAN provider networks.");
127 return super.removeCentralizedRouterAllSwitch(confTx, routers, primarySwitchId);
130 public boolean addCentralizedRouter(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
131 BigInteger primarySwitchId, BigInteger dpnId) {
132 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
133 LOG.debug("VxlanGreConntrackBasedSnatService: handleCentralizedRouter ProviderTypes {}", extNwProviderType);
134 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
135 LOG.debug("handleCentralizedRouter : Skip FLAT/VLAN provider networks.");
138 return super.addCentralizedRouter(confTx, routers, primarySwitchId, dpnId);
141 public boolean removeCentralizedRouter(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
142 BigInteger primarySwitchId, BigInteger dpnId) throws ExecutionException, InterruptedException {
143 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
144 LOG.debug("VxlanGreConntrackBasedSnatService: handleCentralizedRouter ProviderTypes {}", extNwProviderType);
145 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
146 LOG.debug("handleCentralizedRouter : Skip FLAT/VLAN provider networks.");
149 return super.removeCentralizedRouter(confTx, routers, primarySwitchId, dpnId);
153 public boolean addSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
154 BigInteger primarySwitchId, BigInteger dpnId) {
155 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
156 LOG.debug("VxlanGreConntrackBasedSnatService: handleSnat ProviderTypes {}", extNwProviderType);
157 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
158 LOG.debug("handleSnat : Skip FLAT/VLAN provider networks.");
161 return super.addSnat(confTx, routers, primarySwitchId, dpnId);
165 public boolean removeSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
166 BigInteger primarySwitchId, BigInteger dpnId) throws ExecutionException, InterruptedException {
167 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
168 LOG.debug("VxlanGreConntrackBasedSnatService: handleSnat ProviderTypes {}", extNwProviderType);
169 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
170 LOG.debug("handleSnat : Skip FLAT/VLAN provider networks.");
173 return super.removeSnat(confTx, routers, primarySwitchId, dpnId);
177 protected void addSnatSpecificEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
180 LOG.info("installSnatSpecificEntriesForNaptSwitch for router {}",
181 routers.getRouterName());
182 String routerName = routers.getRouterName();
183 Long routerId = NatUtil.getVpnId(dataBroker, routerName);
184 int elanId = NatUtil.getElanInstanceByName(routers.getNetworkId().getValue(), dataBroker)
185 .getElanTag().intValue();
186 /* Install Outbound NAT entries */
188 addSnatMissEntryForPrimrySwch(confTx, dpnId, routerId, elanId);
189 addTerminatingServiceTblEntryForVxlanGre(confTx, dpnId, routerName, routerId, elanId);
190 //Long extNetVpnId = NatUtil.getNetworkVpnIdFromRouterId(dataBroker, routerId);
191 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, routers.getNetworkId());
192 if (vpnUuid == null) {
193 LOG.error("installSnatSpecificEntriesForNaptSwitch: Unable to retrieve external vpn_id for "
194 + "external network {} with routerId {}", routers.getNetworkId(), routerId);
197 Long extNetVpnId = NatUtil.getVpnId(dataBroker, vpnUuid.getValue());
198 LOG.info("installSnatSpecificEntriesForNaptSwitch: external network vpn_id {} for router {}",
199 extNetVpnId, routers.getRouterName());
200 List<ExternalIps> externalIps = routers.getExternalIps();
201 addOutboundTblTrackEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId);
202 addOutboundTblEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId, externalIps, elanId);
203 addNaptPfibFlowForVxlanGre(confTx, routers, dpnId, extNetVpnId);
204 addNaptPfibEntry(confTx, dpnId, routerId);
206 //Install Inbound NAT entries
207 addInboundEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId, externalIps, elanId);
208 if (externalIps.isEmpty()) {
209 LOG.error("installSnatSpecificEntriesForNaptSwitch: No externalIP present for router {}",
213 //The logic now handle only one external IP per router, others if present will be ignored.
214 String externalIp = NatUtil.validateAndAddNetworkMask(externalIps.get(0).getIpAddress());
215 externalRouterListener.handleSnatReverseTraffic(confTx, dpnId, routers, routerId, routerName, externalIp);
219 protected void removeSnatSpecificEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
220 Routers routers, BigInteger dpnId) throws ExecutionException, InterruptedException {
222 LOG.info("installSnatSpecificEntriesForNaptSwitch for router {}",
223 routers.getRouterName());
224 String routerName = routers.getRouterName();
225 Long routerId = NatUtil.getVpnId(dataBroker, routerName);
227 /* Remove Outbound NAT entries */
228 removeSnatMissEntryForPrimrySwch(confTx, dpnId, routerId);
229 removeTerminatingServiceTblEntryForVxlanGre(confTx, dpnId, routerId);
230 //Long extNetVpnId = NatUtil.getNetworkVpnIdFromRouterId(dataBroker, routerId);
231 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, routers.getNetworkId());
232 if (vpnUuid == null) {
233 LOG.error("installSnatSpecificEntriesForNaptSwitch: Unable to retrieve external vpn_id for "
234 + "external network {} with routerId {}", routers.getNetworkId(), routerId);
237 Long extNetVpnId = NatUtil.getVpnId(dataBroker, vpnUuid.getValue());
238 LOG.info("installSnatSpecificEntriesForNaptSwitch: external network vpn_id {} for router {}",
239 extNetVpnId, routers.getRouterName());
240 List<ExternalIps> externalIps = routers.getExternalIps();
241 removeOutboundTblTrackEntryForVxlanGre(confTx, dpnId, routerId);
242 removeOutboundTblEntryForVxlanGre(confTx, dpnId, routerId, externalIps);
243 removeNaptPfibFlowForVxlanGre(confTx, routers, dpnId, extNetVpnId);
244 removeNaptPfibEntry(confTx, dpnId, routerId);
246 //Install Inbound NAT entries
247 removeInboundEntryForVxlanGre(confTx, dpnId, routerId, externalIps);
248 if (externalIps.isEmpty()) {
249 LOG.error("installSnatSpecificEntriesForNaptSwitch: No externalIP present for router {}",
253 //The logic now handle only one external IP per router, others if present will be ignored.
254 String externalIp = NatUtil.validateAndAddNetworkMask(externalIps.get(0).getIpAddress());
255 externalRouterListener.clearFibTsAndReverseTraffic(dpnId, routerId, routers.getNetworkId(),
256 Collections.singletonList(externalIp), null, routers.getExtGwMacAddress(), confTx);
259 protected void addOutboundTblTrackEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
260 Long routerId, Long extNetVpnId) {
261 LOG.info("createOutboundTblTrackEntryForVxlanGre: Install Outbound tracking table flow on dpId {} for "
262 + "routerId {}", dpnId, routerId);
263 List<MatchInfoBase> matches = new ArrayList<>();
264 matches.add(MatchEthernetType.IPV4);
265 matches.add(new NxMatchCtState(SNAT_CT_STATE, SNAT_CT_STATE_MASK));
266 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
268 ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
269 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil.getVpnIdMetadata(extNetVpnId));
270 listActionInfo.add(actionSetFieldMeta);
271 ArrayList<InstructionInfo> instructionInfo = new ArrayList<>();
272 listActionInfo.add(new ActionNxResubmit(NwConstants.NAPT_PFIB_TABLE));
273 instructionInfo.add(new InstructionApplyActions(listActionInfo));
275 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId) + "trkest";
276 addFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY, flowRef,
277 NwConstants.COOKIE_SNAT_TABLE, matches, instructionInfo);
281 protected void removeOutboundTblTrackEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx,
282 BigInteger dpnId, Long routerId) throws ExecutionException, InterruptedException {
283 LOG.info("createOutboundTblTrackEntryForVxlanGre: Install Outbound tracking table flow on dpId {} for "
284 + "routerId {}", dpnId, routerId);
286 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId) + "trkest";
287 removeFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
291 protected void addOutboundTblEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
292 long routerId, Long extNetVpnId, List<ExternalIps> externalIps, int elanId) {
293 LOG.info("createOutboundTblEntryForVxlanGre: Install Outbound table flow on dpId {} for routerId {}", dpnId,
295 List<MatchInfoBase> matches = new ArrayList<>();
296 matches.add(MatchEthernetType.IPV4);
297 matches.add(new NxMatchCtState(TRACKED_NEW_CT_STATE, TRACKED_NEW_CT_MASK));
298 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
299 if (externalIps.isEmpty()) {
300 LOG.error("createOutboundTblEntryForVxlanGre: No externalIP present for routerId {}",
304 //The logic now handle only one external IP per router, others if present will be ignored.
305 String externalIp = externalIps.get(0).getIpAddress();
306 List<ActionInfo> actionsInfos = new ArrayList<>();
307 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
308 .getVpnIdMetadata(extNetVpnId));
309 actionsInfos.add(actionSetFieldMeta);
310 List<ActionNxConntrack.NxCtAction> ctActionsListCommit = new ArrayList<>();
311 int rangePresent = NxActionNatRangePresent.NXNATRANGEIPV4MIN.getIntValue();
312 int flags = NxActionNatFlags.NXNATFSRC.getIntValue();
313 ActionNxConntrack.NxCtAction nxCtActionCommit = new ActionNxConntrack.NxNat(0, flags, rangePresent,
314 IpPrefixOrAddressBuilder.getDefaultInstance(externalIp).getIpAddress(), null,0, 0);
315 ctActionsListCommit.add(nxCtActionCommit);
316 int ctCommitFlag = 1;
317 ActionNxConntrack actionNxConntrackSubmit = new ActionNxConntrack(ctCommitFlag, 0, elanId,
318 NwConstants.NAPT_PFIB_TABLE, ctActionsListCommit);
319 actionsInfos.add(actionNxConntrackSubmit);
320 List<InstructionInfo> instructions = new ArrayList<>();
321 instructions.add(new InstructionApplyActions(actionsInfos));
322 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
323 addFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef, NatConstants.SNAT_NEW_FLOW_PRIORITY,
324 flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
327 protected void removeOutboundTblEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
328 long routerId, List<ExternalIps> externalIps) throws ExecutionException, InterruptedException {
329 LOG.info("createOutboundTblEntryForVxlanGre: Install Outbound table flow on dpId {} for routerId {}", dpnId,
331 if (externalIps.isEmpty()) {
332 LOG.error("createOutboundTblEntryForVxlanGre: No externalIP present for routerId {}",
336 //The logic now handle only one external IP per router, others if present will be ignored.
337 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
338 removeFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
341 protected void addNaptPfibFlowForVxlanGre(TypedWriteTransaction<Configuration> confTx, Routers routers,
342 BigInteger dpnId, Long extNetVpnId) {
343 LOG.info("installNaptPfibFlowForVxlanGre: Install Napt preFibFlow on dpId {} with matching extNetVpnId {} "
344 + "for router {}", dpnId, extNetVpnId, routers.getRouterName());
345 List<MatchInfoBase> matches = new ArrayList<>();
346 matches.add(MatchEthernetType.IPV4);
347 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNetVpnId),
348 MetaDataUtil.METADATA_MASK_VRFID));
349 ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
350 ArrayList<InstructionInfo> instructions = new ArrayList<>();
351 listActionInfo.add(new ActionNxLoadInPort(BigInteger.ZERO));
352 listActionInfo.add(new ActionNxResubmit(NwConstants.L3_FIB_TABLE));
353 instructions.add(new InstructionApplyActions(listActionInfo));
354 String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, extNetVpnId);
355 addFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY,
356 flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
359 protected void removeNaptPfibFlowForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
360 BigInteger dpnId, Long extNetVpnId) throws ExecutionException, InterruptedException {
361 LOG.info("installNaptPfibFlowForVxlanGre: Install Napt preFibFlow on dpId {} with matching extNetVpnId {} "
362 + "for router {}", dpnId, extNetVpnId, routers.getRouterName());
363 String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, extNetVpnId);
364 removeFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef);
367 protected void addInboundEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
368 long routerId, Long extNeVpnId, List<ExternalIps> externalIps, int elanId) {
369 LOG.info("installInboundEntryForVxlanGre: Install Inbound table entry on dpId {} for routerId {}",
371 List<MatchInfoBase> matches = new ArrayList<>();
372 matches.add(MatchEthernetType.IPV4);
373 if (externalIps.isEmpty()) {
374 LOG.error("installInboundEntryForVxlanGre : createInboundTblEntry no externalIP present for routerId {}",
378 String externalIp = externalIps.get(0).getIpAddress();
379 matches.add(new MatchIpv4Destination(externalIp,"32"));
380 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNeVpnId), MetaDataUtil.METADATA_MASK_VRFID));
381 List<ActionInfo> actionsInfos = new ArrayList<>();
382 List<ActionNxConntrack.NxCtAction> ctActionsList = new ArrayList<>();
383 ActionNxConntrack.NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
384 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
385 .getVpnIdMetadata(routerId));
386 actionsInfos.add(actionSetFieldMeta);
387 ctActionsList.add(nxCtAction);
388 ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
389 .NAPT_PFIB_TABLE,ctActionsList);
391 actionsInfos.add(actionNxConntrack);
392 List<InstructionInfo> instructions = new ArrayList<>();
393 instructions.add(new InstructionApplyActions(actionsInfos));
394 String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
395 addFlow(confTx, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY, flowRef,
396 NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
399 protected void removeInboundEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
400 long routerId, List<ExternalIps> externalIps) throws ExecutionException, InterruptedException {
401 LOG.info("removeInboundEntryForVxlanGre: remove Inbound table entry on dpId {} for routerId {}",
403 if (externalIps.isEmpty()) {
404 LOG.error("removeInboundEntryForVxlanGre : createInboundTblEntry no externalIP present for routerId {}",
409 String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
410 removeFlow(confTx, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef);
413 protected void addTerminatingServiceTblEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx,
414 BigInteger dpnId, String routerName, Long routerId, int elanId) {
415 LOG.info("installTerminatingServiceTblEntryForVxlanGre : creating entry for"
416 + "Terminating Service Table for switch {}, routerId {}", dpnId, routerId);
417 List<MatchInfo> matches = new ArrayList<>();
418 matches.add(MatchEthernetType.IPV4);
420 BigInteger tunnelId = BigInteger.valueOf(routerId);
421 if (elanManager.isOpenStackVniSemanticsEnforced()) {
422 tunnelId = NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId);
424 matches.add(new MatchTunnelId(tunnelId));
426 List<ActionInfo> actionsInfos = new ArrayList<>();
427 List<NxCtAction> ctActionsList = new ArrayList<>();
428 NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
429 ctActionsList.add(nxCtAction);
430 ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
431 .OUTBOUND_NAPT_TABLE,ctActionsList);
432 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
433 .getVpnIdMetadata(routerId.longValue()));
434 actionsInfos.add(actionSetFieldMeta);
435 actionsInfos.add(actionNxConntrack);
436 List<InstructionInfo> instructions = new ArrayList<>();
437 instructions.add(new InstructionApplyActions(actionsInfos));
438 String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId.longValue());
439 addFlow(confTx, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY,
440 flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
444 protected void removeTerminatingServiceTblEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx,
445 BigInteger dpnId, Long routerId) throws ExecutionException, InterruptedException {
446 LOG.info("removeTerminatingServiceTblEntryForVxlanGre : removing entry for"
447 + "Terminating Service Table for switch {}, routerId {}", dpnId, routerId);
449 String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId.longValue());
450 removeFlow(confTx, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef);
455 protected void addSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId, Long routerId,
456 String routerName, BigInteger primarySwitchId) {
457 LOG.debug("installSnatMissEntry : Installing SNAT miss entry in switch {}", dpnId);
458 List<ActionInfo> listActionInfoPrimary = new ArrayList<>();
459 String ifNamePrimary = getTunnelInterfaceName(dpnId, primarySwitchId);
460 List<BucketInfo> listBucketInfo = new ArrayList<>();
461 if (ifNamePrimary != null) {
462 LOG.debug("installSnatMissEntry : On Non- Napt switch , Primary Tunnel interface is {}", ifNamePrimary);
463 listActionInfoPrimary = NatUtil.getEgressActionsForInterface(odlInterfaceRpcService, itmManager,
464 interfaceManager, ifNamePrimary, routerId, true);
466 BucketInfo bucketPrimary = new BucketInfo(listActionInfoPrimary);
467 listBucketInfo.add(0, bucketPrimary);
468 LOG.debug("installSnatMissEntry : installSnatMissEntry called for dpnId {} with primaryBucket {} ", dpnId,
469 listBucketInfo.get(0));
470 // Install the select group
471 long groupId = createGroupId(getGroupIdKey(routerName));
472 GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName, GroupTypes.GroupAll,
474 LOG.debug("installSnatMissEntry : installing the SNAT to NAPT GroupEntity:{}", groupEntity);
475 mdsalManager.addGroup(confTx, groupEntity);
476 // Install miss entry pointing to group
477 LOG.debug("installSnatMissEntry : buildSnatFlowEntity is called for dpId {}, routerName {} and groupId {}",
478 dpnId, routerName, groupId);
479 List<MatchInfo> matches = new ArrayList<>();
480 matches.add(new MatchEthernetType(0x0800L));
481 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
483 List<ActionInfo> actionsInfo = new ArrayList<>();
485 BigInteger tunnelId = BigInteger.valueOf(routerId);
486 if (elanManager.isOpenStackVniSemanticsEnforced()) {
487 tunnelId = NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId);
490 actionsInfo.add(new ActionSetFieldTunnelId(tunnelId));
491 LOG.debug("AbstractSnatService : Setting the tunnel to the list of action infos {}", actionsInfo);
492 actionsInfo.add(new ActionGroup(groupId));
493 List<InstructionInfo> instructions = new ArrayList<>();
494 instructions.add(new InstructionApplyActions(actionsInfo));
495 String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
496 addFlow(confTx, dpnId, NwConstants.PSNAT_TABLE, flowRef, NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef,
497 NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
501 protected void removeSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
502 Long routerId, String routerName) throws ExecutionException, InterruptedException {
503 LOG.debug("installSnatMissEntry : Removing SNAT miss entry in switch {}", dpnId);
505 String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
506 removeFlow(confTx, dpnId, NwConstants.PSNAT_TABLE, flowRef);