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.util.ArrayList;
11 import java.util.Collections;
12 import java.util.List;
14 import java.util.concurrent.ExecutionException;
15 import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
16 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
17 import org.opendaylight.genius.mdsalutil.ActionInfo;
18 import org.opendaylight.genius.mdsalutil.BucketInfo;
19 import org.opendaylight.genius.mdsalutil.GroupEntity;
20 import org.opendaylight.genius.mdsalutil.InstructionInfo;
21 import org.opendaylight.genius.mdsalutil.MDSALUtil;
22 import org.opendaylight.genius.mdsalutil.MatchInfo;
23 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
24 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
25 import org.opendaylight.genius.mdsalutil.NwConstants;
26 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
27 import org.opendaylight.genius.mdsalutil.actions.ActionNxConntrack;
28 import org.opendaylight.genius.mdsalutil.actions.ActionNxConntrack.NxCtAction;
29 import org.opendaylight.genius.mdsalutil.actions.ActionNxLoadInPort;
30 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
31 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldMeta;
32 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldTunnelId;
33 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
34 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
35 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
36 import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Destination;
37 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
38 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
39 import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchCtState;
40 import org.opendaylight.mdsal.binding.api.DataBroker;
41 import org.opendaylight.mdsal.binding.util.Datastore.Configuration;
42 import org.opendaylight.mdsal.binding.util.TypedReadWriteTransaction;
43 import org.opendaylight.mdsal.binding.util.TypedWriteTransaction;
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.netvirt.natservice.rev160111.ext.routers.routers.ExternalIpsKey;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.types.rev160517.IpPrefixOrAddressBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.NxActionNatFlags;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.NxActionNatRangePresent;
60 import org.opendaylight.yangtools.yang.common.Uint32;
61 import org.opendaylight.yangtools.yang.common.Uint64;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
65 public class VxlanGreConntrackBasedSnatService extends ConntrackBasedSnatService {
67 private static final Logger LOG = LoggerFactory.getLogger(VxlanGreConntrackBasedSnatService.class);
68 private final ExternalRoutersListener externalRouterListener;
69 private final IElanService elanManager;
70 private final NatOverVxlanUtil natOverVxlanUtil;
72 public VxlanGreConntrackBasedSnatService(DataBroker dataBroker, IMdsalApiManager mdsalManager,
73 ItmRpcService itmManager, OdlInterfaceRpcService odlInterfaceRpcService,
74 IdManagerService idManager, NAPTSwitchSelector naptSwitchSelector,
75 ExternalRoutersListener externalRouterListener, IElanService elanManager,
76 IInterfaceManager interfaceManager,
77 IVpnFootprintService vpnFootprintService,
78 IFibManager fibManager, NatDataUtil natDataUtil,
79 DataTreeEventCallbackRegistrar eventCallbacks,
80 NatOverVxlanUtil natOverVxlanUtil) {
81 super(dataBroker, mdsalManager, itmManager, idManager, naptSwitchSelector, odlInterfaceRpcService,
82 interfaceManager, vpnFootprintService, fibManager, natDataUtil, eventCallbacks);
83 this.externalRouterListener = externalRouterListener;
84 this.elanManager = elanManager;
85 this.natOverVxlanUtil = natOverVxlanUtil;
89 public boolean addSnatAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
90 Uint64 primarySwitchId) {
91 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
92 LOG.debug("VxlanGreConntrackBasedSnatService: handleSnatAllSwitch ProviderTypes {}", extNwProviderType);
93 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
94 LOG.debug("handleSnatAllSwitch : Skip FLAT/VLAN provider networks.");
97 return super.addSnatAllSwitch(confTx, routers, primarySwitchId);
101 public boolean removeSnatAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
102 Uint64 primarySwitchId) throws ExecutionException, InterruptedException {
103 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
104 LOG.debug("VxlanGreConntrackBasedSnatService: handleSnatAllSwitch ProviderTypes {}", extNwProviderType);
105 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
106 LOG.debug("handleSnatAllSwitch : Skip FLAT/VLAN provider networks.");
109 return super.removeSnatAllSwitch(confTx, routers, primarySwitchId);
112 public boolean addCentralizedRouterAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
113 Uint64 primarySwitchId) {
114 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
115 LOG.debug("VxlanGreConntrackBasedSnatService: handleCentralizedRouterAllSwitch ProviderTypes {}",
117 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
118 LOG.debug("handleCentralizedRouterAllSwitch : Skip FLAT/VLAN provider networks.");
121 return super.addCentralizedRouterAllSwitch(confTx, routers, primarySwitchId);
124 public boolean removeCentralizedRouterAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
125 Uint64 primarySwitchId) throws ExecutionException, InterruptedException {
126 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
127 LOG.debug("VxlanGreConntrackBasedSnatService: handleCentralizedRouterAllSwitch ProviderTypes {}",
129 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
130 LOG.debug("handleCentralizedRouterAllSwitch : Skip FLAT/VLAN provider networks.");
133 return super.removeCentralizedRouterAllSwitch(confTx, routers, primarySwitchId);
136 public boolean addCentralizedRouter(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
137 Uint64 primarySwitchId, Uint64 dpnId) {
138 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
139 LOG.debug("VxlanGreConntrackBasedSnatService: handleCentralizedRouter ProviderTypes {}", extNwProviderType);
140 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
141 LOG.debug("handleCentralizedRouter : Skip FLAT/VLAN provider networks.");
144 return super.addCentralizedRouter(confTx, routers, primarySwitchId, dpnId);
147 public boolean removeCentralizedRouter(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
148 Uint64 primarySwitchId, Uint64 dpnId) throws ExecutionException, InterruptedException {
149 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
150 LOG.debug("VxlanGreConntrackBasedSnatService: handleCentralizedRouter ProviderTypes {}", extNwProviderType);
151 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
152 LOG.debug("handleCentralizedRouter : Skip FLAT/VLAN provider networks.");
155 return super.removeCentralizedRouter(confTx, routers, primarySwitchId, dpnId);
159 public boolean addSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
160 Uint64 primarySwitchId, Uint64 dpnId) {
161 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
162 LOG.debug("VxlanGreConntrackBasedSnatService: handleSnat ProviderTypes {}", extNwProviderType);
163 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
164 LOG.debug("handleSnat : Skip FLAT/VLAN provider networks.");
167 return super.addSnat(confTx, routers, primarySwitchId, dpnId);
171 public boolean removeSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
172 Uint64 primarySwitchId, Uint64 dpnId) throws ExecutionException, InterruptedException {
173 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
174 LOG.debug("VxlanGreConntrackBasedSnatService: handleSnat ProviderTypes {}", extNwProviderType);
175 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
176 LOG.debug("handleSnat : Skip FLAT/VLAN provider networks.");
179 return super.removeSnat(confTx, routers, primarySwitchId, dpnId);
183 protected void addSnatSpecificEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
186 LOG.info("installSnatSpecificEntriesForNaptSwitch for router {}",
187 routers.getRouterName());
188 String routerName = routers.getRouterName();
189 Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
190 int elanId = NatUtil.getElanInstanceByName(routers.getNetworkId().getValue(), dataBroker)
191 .getElanTag().intValue();
192 /* Install Outbound NAT entries */
194 addSnatMissEntryForPrimrySwch(confTx, dpnId, routerId, elanId);
195 addTerminatingServiceTblEntryForVxlanGre(confTx, dpnId, routerName, routerId, elanId);
196 //Long extNetVpnId = NatUtil.getNetworkVpnIdFromRouterId(dataBroker, routerId);
197 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, routers.getNetworkId());
198 if (vpnUuid == null) {
199 LOG.error("installSnatSpecificEntriesForNaptSwitch: Unable to retrieve external vpn_id for "
200 + "external network {} with routerId {}", routers.getNetworkId(), routerId);
203 Uint32 extNetVpnId = NatUtil.getVpnId(dataBroker, vpnUuid.getValue());
204 LOG.info("installSnatSpecificEntriesForNaptSwitch: external network vpn_id {} for router {}",
205 extNetVpnId, routers.getRouterName());
206 Map<ExternalIpsKey, ExternalIps> keyExternalIpsMap = routers.nonnullExternalIps();
207 addOutboundTblTrackEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId);
208 addOutboundTblEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId,
209 new ArrayList<ExternalIps>(keyExternalIpsMap.values()), elanId);
210 addNaptPfibFlowForVxlanGre(confTx, routers, dpnId, extNetVpnId);
211 addNaptPfibEntry(confTx, dpnId, routerId);
213 //Install Inbound NAT entries
214 addInboundEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId,
215 new ArrayList<ExternalIps>(keyExternalIpsMap.values()), elanId);
216 if (keyExternalIpsMap.isEmpty()) {
217 LOG.error("installSnatSpecificEntriesForNaptSwitch: No externalIP present for router {}",
221 //The logic now handle only one external IP per router, others if present will be ignored.
222 String externalIp = NatUtil.validateAndAddNetworkMask(
223 new ArrayList<ExternalIps>(keyExternalIpsMap.values()).get(0).getIpAddress());
224 externalRouterListener.handleSnatReverseTraffic(confTx, dpnId, routers, routerId, routerName, externalIp);
228 protected void removeSnatSpecificEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
229 Routers routers, Uint64 dpnId) throws ExecutionException, InterruptedException {
231 LOG.info("installSnatSpecificEntriesForNaptSwitch for router {}",
232 routers.getRouterName());
233 String routerName = routers.getRouterName();
234 Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
236 /* Remove Outbound NAT entries */
237 removeSnatMissEntryForPrimrySwch(confTx, dpnId, routerId);
238 removeTerminatingServiceTblEntryForVxlanGre(confTx, dpnId, routerId);
239 //Long extNetVpnId = NatUtil.getNetworkVpnIdFromRouterId(dataBroker, routerId);
240 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, routers.getNetworkId());
241 if (vpnUuid == null) {
242 LOG.error("installSnatSpecificEntriesForNaptSwitch: Unable to retrieve external vpn_id for "
243 + "external network {} with routerId {}", routers.getNetworkId(), routerId);
246 Uint32 extNetVpnId = NatUtil.getVpnId(dataBroker, vpnUuid.getValue());
247 LOG.info("installSnatSpecificEntriesForNaptSwitch: external network vpn_id {} for router {}",
248 extNetVpnId, routers.getRouterName());
249 Map<ExternalIpsKey, ExternalIps> keyExternalIpsMap = routers.nonnullExternalIps();
250 removeOutboundTblTrackEntryForVxlanGre(confTx, dpnId, routerId);
251 removeOutboundTblEntryForVxlanGre(confTx, dpnId, routerId,
252 new ArrayList<ExternalIps>(keyExternalIpsMap.values()));
253 removeNaptPfibFlowForVxlanGre(confTx, routers, dpnId, extNetVpnId);
254 removeNaptPfibEntry(confTx, dpnId, routerId);
256 //Install Inbound NAT entries
257 removeInboundEntryForVxlanGre(confTx, dpnId, routerId, new ArrayList<ExternalIps>(keyExternalIpsMap.values()));
258 if (keyExternalIpsMap.isEmpty()) {
259 LOG.error("installSnatSpecificEntriesForNaptSwitch: No externalIP present for router {}",
263 //The logic now handle only one external IP per router, others if present will be ignored.
264 String externalIp = NatUtil.validateAndAddNetworkMask(
265 new ArrayList<ExternalIps>(keyExternalIpsMap.values()).get(0).getIpAddress());
266 externalRouterListener.clearFibTsAndReverseTraffic(dpnId, routerId, routers.getNetworkId(),
267 Collections.singletonList(externalIp), null, routers.getExtGwMacAddress(), confTx);
270 protected void addOutboundTblTrackEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, Uint64 dpnId,
271 Uint32 routerId, Uint32 extNetVpnId) {
272 LOG.info("createOutboundTblTrackEntryForVxlanGre: Install Outbound tracking table flow on dpId {} for "
273 + "routerId {}", dpnId, routerId);
274 List<MatchInfoBase> matches = new ArrayList<>();
275 matches.add(MatchEthernetType.IPV4);
276 matches.add(new NxMatchCtState(SNAT_CT_STATE, SNAT_CT_STATE_MASK));
277 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId.longValue()),
278 MetaDataUtil.METADATA_MASK_VRFID));
280 ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
281 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(
282 MetaDataUtil.getVpnIdMetadata(extNetVpnId.longValue()));
283 listActionInfo.add(actionSetFieldMeta);
284 ArrayList<InstructionInfo> instructionInfo = new ArrayList<>();
285 listActionInfo.add(new ActionNxResubmit(NwConstants.NAPT_PFIB_TABLE));
286 instructionInfo.add(new InstructionApplyActions(listActionInfo));
288 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId) + "trkest";
289 NatUtil.addFlow(confTx, mdsalManager, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef,
290 NatConstants.SNAT_TRK_FLOW_PRIORITY, flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructionInfo);
294 protected void removeOutboundTblTrackEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx,
295 Uint64 dpnId, Uint32 routerId) throws ExecutionException, InterruptedException {
296 LOG.info("createOutboundTblTrackEntryForVxlanGre: Install Outbound tracking table flow on dpId {} for "
297 + "routerId {}", dpnId, routerId);
299 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId) + "trkest";
300 NatUtil.removeFlow(confTx, mdsalManager, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
304 protected void addOutboundTblEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, Uint64 dpnId,
305 Uint32 routerId, Uint32 extNetVpnId, List<ExternalIps> externalIps,
307 LOG.info("createOutboundTblEntryForVxlanGre: Install Outbound table flow on dpId {} for routerId {}", dpnId,
309 List<MatchInfoBase> matches = new ArrayList<>();
310 matches.add(MatchEthernetType.IPV4);
311 matches.add(new NxMatchCtState(TRACKED_NEW_CT_STATE, TRACKED_NEW_CT_MASK));
312 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId.longValue()),
313 MetaDataUtil.METADATA_MASK_VRFID));
314 if (externalIps.isEmpty()) {
315 LOG.error("createOutboundTblEntryForVxlanGre: No externalIP present for routerId {}",
319 //The logic now handle only one external IP per router, others if present will be ignored.
320 String externalIp = externalIps.get(0).getIpAddress();
321 List<ActionInfo> actionsInfos = new ArrayList<>();
322 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
323 .getVpnIdMetadata(extNetVpnId.longValue()));
324 actionsInfos.add(actionSetFieldMeta);
325 List<ActionNxConntrack.NxCtAction> ctActionsListCommit = new ArrayList<>();
326 int rangePresent = NxActionNatRangePresent.NXNATRANGEIPV4MIN.getIntValue();
327 int flags = NxActionNatFlags.NXNATFSRC.getIntValue();
328 ActionNxConntrack.NxCtAction nxCtActionCommit = new ActionNxConntrack.NxNat(0, flags, rangePresent,
329 IpPrefixOrAddressBuilder.getDefaultInstance(externalIp).getIpAddress(), null,0, 0);
330 ctActionsListCommit.add(nxCtActionCommit);
331 int ctCommitFlag = 1;
332 ActionNxConntrack actionNxConntrackSubmit = new ActionNxConntrack(ctCommitFlag, 0, elanId,
333 NwConstants.NAPT_PFIB_TABLE, ctActionsListCommit);
334 actionsInfos.add(actionNxConntrackSubmit);
335 List<InstructionInfo> instructions = new ArrayList<>();
336 instructions.add(new InstructionApplyActions(actionsInfos));
337 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
338 NatUtil.addFlow(confTx, mdsalManager, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef,
339 NatConstants.SNAT_NEW_FLOW_PRIORITY, flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
342 protected void removeOutboundTblEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, Uint64 dpnId,
343 Uint32 routerId, List<ExternalIps> externalIps)
344 throws ExecutionException, InterruptedException {
345 LOG.info("createOutboundTblEntryForVxlanGre: Install Outbound table flow on dpId {} for routerId {}", dpnId,
347 if (externalIps.isEmpty()) {
348 LOG.error("createOutboundTblEntryForVxlanGre: No externalIP present for routerId {}",
352 //The logic now handle only one external IP per router, others if present will be ignored.
353 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
354 NatUtil.removeFlow(confTx, mdsalManager, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
357 protected void addNaptPfibFlowForVxlanGre(TypedWriteTransaction<Configuration> confTx, Routers routers,
358 Uint64 dpnId, Uint32 extNetVpnId) {
359 LOG.info("installNaptPfibFlowForVxlanGre: Install Napt preFibFlow on dpId {} with matching extNetVpnId {} "
360 + "for router {}", dpnId, extNetVpnId, routers.getRouterName());
361 List<MatchInfoBase> matches = new ArrayList<>();
362 matches.add(MatchEthernetType.IPV4);
363 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNetVpnId.longValue()),
364 MetaDataUtil.METADATA_MASK_VRFID));
365 ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
366 ArrayList<InstructionInfo> instructions = new ArrayList<>();
367 listActionInfo.add(new ActionNxLoadInPort(Uint64.ZERO));
368 listActionInfo.add(new ActionNxResubmit(NwConstants.L3_FIB_TABLE));
369 instructions.add(new InstructionApplyActions(listActionInfo));
370 String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, extNetVpnId);
371 NatUtil.addFlow(confTx, mdsalManager, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef,
372 NatConstants.SNAT_TRK_FLOW_PRIORITY, flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
375 protected void removeNaptPfibFlowForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
376 Uint64 dpnId, Uint32 extNetVpnId) throws ExecutionException, InterruptedException {
377 LOG.info("installNaptPfibFlowForVxlanGre: Install Napt preFibFlow on dpId {} with matching extNetVpnId {} "
378 + "for router {}", dpnId, extNetVpnId, routers.getRouterName());
379 String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, extNetVpnId);
380 NatUtil.removeFlow(confTx, mdsalManager, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef);
383 protected void addInboundEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, Uint64 dpnId,
384 Uint32 routerId, Uint32 extNeVpnId, List<ExternalIps> externalIps,
386 LOG.info("installInboundEntryForVxlanGre: Install Inbound table entry on dpId {} for routerId {}",
388 List<MatchInfoBase> matches = new ArrayList<>();
389 matches.add(MatchEthernetType.IPV4);
390 if (externalIps.isEmpty()) {
391 LOG.error("installInboundEntryForVxlanGre : createInboundTblEntry no externalIP present for routerId {}",
395 String externalIp = externalIps.get(0).getIpAddress();
396 matches.add(new MatchIpv4Destination(externalIp,"32"));
397 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNeVpnId.longValue()),
398 MetaDataUtil.METADATA_MASK_VRFID));
399 List<ActionInfo> actionsInfos = new ArrayList<>();
400 List<ActionNxConntrack.NxCtAction> ctActionsList = new ArrayList<>();
401 ActionNxConntrack.NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
402 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
403 .getVpnIdMetadata(routerId.longValue()));
404 actionsInfos.add(actionSetFieldMeta);
405 ctActionsList.add(nxCtAction);
406 ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
407 .NAPT_PFIB_TABLE,ctActionsList);
409 actionsInfos.add(actionNxConntrack);
410 List<InstructionInfo> instructions = new ArrayList<>();
411 instructions.add(new InstructionApplyActions(actionsInfos));
412 String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
413 NatUtil.addFlow(confTx, mdsalManager, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef,
414 NatConstants.DEFAULT_TS_FLOW_PRIORITY, flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
417 protected void removeInboundEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, Uint64 dpnId,
418 Uint32 routerId, List<ExternalIps> externalIps)
419 throws ExecutionException, InterruptedException {
420 LOG.info("removeInboundEntryForVxlanGre: remove Inbound table entry on dpId {} for routerId {}",
422 if (externalIps.isEmpty()) {
423 LOG.error("removeInboundEntryForVxlanGre : createInboundTblEntry no externalIP present for routerId {}",
428 String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
429 NatUtil.removeFlow(confTx, mdsalManager, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef);
432 protected void addTerminatingServiceTblEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx,
433 Uint64 dpnId, String routerName, Uint32 routerId, int elanId) {
434 LOG.info("installTerminatingServiceTblEntryForVxlanGre : creating entry for"
435 + "Terminating Service Table for switch {}, routerId {}", dpnId, routerId);
436 List<MatchInfo> matches = new ArrayList<>();
437 matches.add(MatchEthernetType.IPV4);
439 Uint64 tunnelId = Uint64.valueOf(routerId);
440 if (elanManager.isOpenStackVniSemanticsEnforced()) {
441 tunnelId = natOverVxlanUtil.getRouterVni(routerName, routerId);
443 matches.add(new MatchTunnelId(tunnelId));
445 List<ActionInfo> actionsInfos = new ArrayList<>();
446 List<NxCtAction> ctActionsList = new ArrayList<>();
447 NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
448 ctActionsList.add(nxCtAction);
449 ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
450 .OUTBOUND_NAPT_TABLE,ctActionsList);
451 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
452 .getVpnIdMetadata(routerId.longValue()));
453 actionsInfos.add(actionSetFieldMeta);
454 actionsInfos.add(actionNxConntrack);
455 List<InstructionInfo> instructions = new ArrayList<>();
456 instructions.add(new InstructionApplyActions(actionsInfos));
457 String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId);
458 NatUtil.addFlow(confTx, mdsalManager, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef,
459 NatConstants.DEFAULT_TS_FLOW_PRIORITY, flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
463 protected void removeTerminatingServiceTblEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx,
464 Uint64 dpnId, Uint32 routerId) throws ExecutionException, InterruptedException {
465 LOG.info("removeTerminatingServiceTblEntryForVxlanGre : removing entry for"
466 + "Terminating Service Table for switch {}, routerId {}", dpnId, routerId);
468 String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId);
469 NatUtil.removeFlow(confTx, mdsalManager, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef);
474 protected void addSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, Uint64 dpnId, Uint32 routerId,
475 String routerName, Uint64 primarySwitchId) {
476 LOG.debug("addSnatMissEntry : Installing SNAT miss entry in switch {}", dpnId);
477 List<ActionInfo> listActionInfoPrimary = new ArrayList<>();
478 String ifNamePrimary = NatUtil.getTunnelInterfaceName(dpnId, primarySwitchId, itmManager);
479 List<BucketInfo> listBucketInfo = new ArrayList<>();
480 if (ifNamePrimary != null) {
481 LOG.debug("addSnatMissEntry : On Non- Napt switch , Primary Tunnel interface is {}", ifNamePrimary);
482 listActionInfoPrimary = NatUtil.getEgressActionsForInterface(odlInterfaceRpcService, itmManager,
483 interfaceManager, ifNamePrimary, routerId, true);
485 BucketInfo bucketPrimary = new BucketInfo(listActionInfoPrimary);
486 listBucketInfo.add(0, bucketPrimary);
487 LOG.debug("addSnatMissEntry : addSnatMissEntry called for dpnId {} with primaryBucket {} ", dpnId,
488 listBucketInfo.get(0));
489 // Install the select group
490 Uint32 groupId = NatUtil.getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME, getGroupIdKey(routerName));
491 if (groupId != NatConstants.INVALID_ID) {
492 GroupEntity groupEntity = MDSALUtil
493 .buildGroupEntity(dpnId, groupId.longValue(), routerName, GroupTypes.GroupAll,
495 LOG.debug("addSnatMissEntry : installing the SNAT to NAPT GroupEntity:{}", groupEntity);
496 mdsalManager.addGroup(confTx, groupEntity);
497 // Install miss entry pointing to group
499 "addSnatMissEntry : buildSnatFlowEntity is called for dpId {}, routerName {} and groupId {}",
500 dpnId, routerName, groupId);
501 List<MatchInfo> matches = new ArrayList<>();
502 matches.add(new MatchEthernetType(0x0800L));
503 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId.longValue()),
504 MetaDataUtil.METADATA_MASK_VRFID));
506 List<ActionInfo> actionsInfo = new ArrayList<>();
508 Uint64 tunnelId = Uint64.valueOf(routerId);
509 if (elanManager.isOpenStackVniSemanticsEnforced()) {
510 tunnelId = natOverVxlanUtil.getRouterVni(routerName, routerId);
513 actionsInfo.add(new ActionSetFieldTunnelId(tunnelId));
514 LOG.debug("addSnatMissEntry : Setting the tunnel to the list of action infos {}",
516 actionsInfo.add(new ActionGroup(groupId.longValue()));
517 List<InstructionInfo> instructions = new ArrayList<>();
518 instructions.add(new InstructionApplyActions(actionsInfo));
519 String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
520 NatUtil.addFlow(confTx, mdsalManager, dpnId, NwConstants.PSNAT_TABLE, flowRef,
521 NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef, NwConstants.COOKIE_SNAT_TABLE,
525 LOG.error("installSnatMissEntry: Unable to get groupId for router:{}", routerName);
530 protected void removeSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, Uint64 dpnId,
531 Uint32 routerId, String routerName)
532 throws ExecutionException, InterruptedException {
533 LOG.debug("installSnatMissEntry : Removing SNAT miss entry in switch {}", dpnId);
535 String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
536 NatUtil.removeFlow(confTx, mdsalManager, dpnId, NwConstants.PSNAT_TABLE, flowRef);