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;
13 import java.util.concurrent.ExecutionException;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
16 import org.opendaylight.genius.infra.Datastore.Configuration;
17 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
18 import org.opendaylight.genius.infra.TypedWriteTransaction;
19 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
20 import org.opendaylight.genius.mdsalutil.ActionInfo;
21 import org.opendaylight.genius.mdsalutil.BucketInfo;
22 import org.opendaylight.genius.mdsalutil.GroupEntity;
23 import org.opendaylight.genius.mdsalutil.InstructionInfo;
24 import org.opendaylight.genius.mdsalutil.MDSALUtil;
25 import org.opendaylight.genius.mdsalutil.MatchInfo;
26 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
27 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
28 import org.opendaylight.genius.mdsalutil.NwConstants;
29 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
30 import org.opendaylight.genius.mdsalutil.actions.ActionNxConntrack;
31 import org.opendaylight.genius.mdsalutil.actions.ActionNxConntrack.NxCtAction;
32 import org.opendaylight.genius.mdsalutil.actions.ActionNxLoadInPort;
33 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
34 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldMeta;
35 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldTunnelId;
36 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
37 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
38 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
39 import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Destination;
40 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
41 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
42 import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchCtState;
43 import org.opendaylight.netvirt.elanmanager.api.IElanService;
44 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
45 import org.opendaylight.netvirt.natservice.ha.NatDataUtil;
46 import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.types.rev160517.IpPrefixOrAddressBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.NxActionNatFlags;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.NxActionNatRangePresent;
58 import org.opendaylight.yangtools.yang.common.Uint32;
59 import org.opendaylight.yangtools.yang.common.Uint64;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
63 public class VxlanGreConntrackBasedSnatService extends ConntrackBasedSnatService {
65 private static final Logger LOG = LoggerFactory.getLogger(VxlanGreConntrackBasedSnatService.class);
66 private final ExternalRoutersListener externalRouterListener;
67 private final IElanService elanManager;
68 private final NatOverVxlanUtil natOverVxlanUtil;
70 public VxlanGreConntrackBasedSnatService(DataBroker dataBroker, IMdsalApiManager mdsalManager,
71 ItmRpcService itmManager, OdlInterfaceRpcService odlInterfaceRpcService,
72 IdManagerService idManager, NAPTSwitchSelector naptSwitchSelector,
73 ExternalRoutersListener externalRouterListener, IElanService elanManager,
74 IInterfaceManager interfaceManager,
75 IVpnFootprintService vpnFootprintService,
76 IFibManager fibManager, NatDataUtil natDataUtil,
77 DataTreeEventCallbackRegistrar eventCallbacks,
78 NatOverVxlanUtil natOverVxlanUtil) {
79 super(dataBroker, mdsalManager, itmManager, idManager, naptSwitchSelector, odlInterfaceRpcService,
80 interfaceManager, vpnFootprintService, fibManager, natDataUtil, eventCallbacks);
81 this.externalRouterListener = externalRouterListener;
82 this.elanManager = elanManager;
83 this.natOverVxlanUtil = natOverVxlanUtil;
87 public boolean addSnatAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
88 Uint64 primarySwitchId) {
89 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
90 LOG.debug("VxlanGreConntrackBasedSnatService: handleSnatAllSwitch ProviderTypes {}", extNwProviderType);
91 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
92 LOG.debug("handleSnatAllSwitch : Skip FLAT/VLAN provider networks.");
95 return super.addSnatAllSwitch(confTx, routers, primarySwitchId);
99 public boolean removeSnatAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
100 Uint64 primarySwitchId) throws ExecutionException, InterruptedException {
101 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
102 LOG.debug("VxlanGreConntrackBasedSnatService: handleSnatAllSwitch ProviderTypes {}", extNwProviderType);
103 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
104 LOG.debug("handleSnatAllSwitch : Skip FLAT/VLAN provider networks.");
107 return super.removeSnatAllSwitch(confTx, routers, primarySwitchId);
110 public boolean addCentralizedRouterAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
111 Uint64 primarySwitchId) {
112 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
113 LOG.debug("VxlanGreConntrackBasedSnatService: handleCentralizedRouterAllSwitch ProviderTypes {}",
115 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
116 LOG.debug("handleCentralizedRouterAllSwitch : Skip FLAT/VLAN provider networks.");
119 return super.addCentralizedRouterAllSwitch(confTx, routers, primarySwitchId);
122 public boolean removeCentralizedRouterAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
123 Uint64 primarySwitchId) throws ExecutionException, InterruptedException {
124 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
125 LOG.debug("VxlanGreConntrackBasedSnatService: handleCentralizedRouterAllSwitch ProviderTypes {}",
127 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
128 LOG.debug("handleCentralizedRouterAllSwitch : Skip FLAT/VLAN provider networks.");
131 return super.removeCentralizedRouterAllSwitch(confTx, routers, primarySwitchId);
134 public boolean addCentralizedRouter(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
135 Uint64 primarySwitchId, Uint64 dpnId) {
136 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
137 LOG.debug("VxlanGreConntrackBasedSnatService: handleCentralizedRouter ProviderTypes {}", extNwProviderType);
138 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
139 LOG.debug("handleCentralizedRouter : Skip FLAT/VLAN provider networks.");
142 return super.addCentralizedRouter(confTx, routers, primarySwitchId, dpnId);
145 public boolean removeCentralizedRouter(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
146 Uint64 primarySwitchId, Uint64 dpnId) throws ExecutionException, InterruptedException {
147 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
148 LOG.debug("VxlanGreConntrackBasedSnatService: handleCentralizedRouter ProviderTypes {}", extNwProviderType);
149 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
150 LOG.debug("handleCentralizedRouter : Skip FLAT/VLAN provider networks.");
153 return super.removeCentralizedRouter(confTx, routers, primarySwitchId, dpnId);
157 public boolean addSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
158 Uint64 primarySwitchId, Uint64 dpnId) {
159 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
160 LOG.debug("VxlanGreConntrackBasedSnatService: handleSnat ProviderTypes {}", extNwProviderType);
161 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
162 LOG.debug("handleSnat : Skip FLAT/VLAN provider networks.");
165 return super.addSnat(confTx, routers, primarySwitchId, dpnId);
169 public boolean removeSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
170 Uint64 primarySwitchId, Uint64 dpnId) throws ExecutionException, InterruptedException {
171 ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
172 LOG.debug("VxlanGreConntrackBasedSnatService: handleSnat ProviderTypes {}", extNwProviderType);
173 if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
174 LOG.debug("handleSnat : Skip FLAT/VLAN provider networks.");
177 return super.removeSnat(confTx, routers, primarySwitchId, dpnId);
181 protected void addSnatSpecificEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
184 LOG.info("installSnatSpecificEntriesForNaptSwitch for router {}",
185 routers.getRouterName());
186 String routerName = routers.getRouterName();
187 Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
188 int elanId = NatUtil.getElanInstanceByName(routers.getNetworkId().getValue(), dataBroker)
189 .getElanTag().intValue();
190 /* Install Outbound NAT entries */
192 addSnatMissEntryForPrimrySwch(confTx, dpnId, routerId, elanId);
193 addTerminatingServiceTblEntryForVxlanGre(confTx, dpnId, routerName, routerId, elanId);
194 //Long extNetVpnId = NatUtil.getNetworkVpnIdFromRouterId(dataBroker, routerId);
195 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, routers.getNetworkId());
196 if (vpnUuid == null) {
197 LOG.error("installSnatSpecificEntriesForNaptSwitch: Unable to retrieve external vpn_id for "
198 + "external network {} with routerId {}", routers.getNetworkId(), routerId);
201 Uint32 extNetVpnId = NatUtil.getVpnId(dataBroker, vpnUuid.getValue());
202 LOG.info("installSnatSpecificEntriesForNaptSwitch: external network vpn_id {} for router {}",
203 extNetVpnId, routers.getRouterName());
204 List<ExternalIps> externalIps = routers.getExternalIps();
205 addOutboundTblTrackEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId);
206 addOutboundTblEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId, externalIps, elanId);
207 addNaptPfibFlowForVxlanGre(confTx, routers, dpnId, extNetVpnId);
208 addNaptPfibEntry(confTx, dpnId, routerId);
210 //Install Inbound NAT entries
211 addInboundEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId, externalIps, elanId);
212 if (externalIps.isEmpty()) {
213 LOG.error("installSnatSpecificEntriesForNaptSwitch: No externalIP present for router {}",
217 //The logic now handle only one external IP per router, others if present will be ignored.
218 String externalIp = NatUtil.validateAndAddNetworkMask(externalIps.get(0).getIpAddress());
219 externalRouterListener.handleSnatReverseTraffic(confTx, dpnId, routers, routerId, routerName, externalIp);
223 protected void removeSnatSpecificEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
224 Routers routers, Uint64 dpnId) throws ExecutionException, InterruptedException {
226 LOG.info("installSnatSpecificEntriesForNaptSwitch for router {}",
227 routers.getRouterName());
228 String routerName = routers.getRouterName();
229 Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
231 /* Remove Outbound NAT entries */
232 removeSnatMissEntryForPrimrySwch(confTx, dpnId, routerId);
233 removeTerminatingServiceTblEntryForVxlanGre(confTx, dpnId, routerId);
234 //Long extNetVpnId = NatUtil.getNetworkVpnIdFromRouterId(dataBroker, routerId);
235 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, routers.getNetworkId());
236 if (vpnUuid == null) {
237 LOG.error("installSnatSpecificEntriesForNaptSwitch: Unable to retrieve external vpn_id for "
238 + "external network {} with routerId {}", routers.getNetworkId(), routerId);
241 Uint32 extNetVpnId = NatUtil.getVpnId(dataBroker, vpnUuid.getValue());
242 LOG.info("installSnatSpecificEntriesForNaptSwitch: external network vpn_id {} for router {}",
243 extNetVpnId, routers.getRouterName());
244 List<ExternalIps> externalIps = routers.getExternalIps();
245 removeOutboundTblTrackEntryForVxlanGre(confTx, dpnId, routerId);
246 removeOutboundTblEntryForVxlanGre(confTx, dpnId, routerId, externalIps);
247 removeNaptPfibFlowForVxlanGre(confTx, routers, dpnId, extNetVpnId);
248 removeNaptPfibEntry(confTx, dpnId, routerId);
250 //Install Inbound NAT entries
251 removeInboundEntryForVxlanGre(confTx, dpnId, routerId, externalIps);
252 if (externalIps.isEmpty()) {
253 LOG.error("installSnatSpecificEntriesForNaptSwitch: No externalIP present for router {}",
257 //The logic now handle only one external IP per router, others if present will be ignored.
258 String externalIp = NatUtil.validateAndAddNetworkMask(externalIps.get(0).getIpAddress());
259 externalRouterListener.clearFibTsAndReverseTraffic(dpnId, routerId, routers.getNetworkId(),
260 Collections.singletonList(externalIp), null, routers.getExtGwMacAddress(), confTx);
263 protected void addOutboundTblTrackEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, Uint64 dpnId,
264 Uint32 routerId, Uint32 extNetVpnId) {
265 LOG.info("createOutboundTblTrackEntryForVxlanGre: Install Outbound tracking table flow on dpId {} for "
266 + "routerId {}", dpnId, routerId);
267 List<MatchInfoBase> matches = new ArrayList<>();
268 matches.add(MatchEthernetType.IPV4);
269 matches.add(new NxMatchCtState(SNAT_CT_STATE, SNAT_CT_STATE_MASK));
270 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId.longValue()),
271 MetaDataUtil.METADATA_MASK_VRFID));
273 ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
274 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(
275 MetaDataUtil.getVpnIdMetadata(extNetVpnId.longValue()));
276 listActionInfo.add(actionSetFieldMeta);
277 ArrayList<InstructionInfo> instructionInfo = new ArrayList<>();
278 listActionInfo.add(new ActionNxResubmit(NwConstants.NAPT_PFIB_TABLE));
279 instructionInfo.add(new InstructionApplyActions(listActionInfo));
281 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId) + "trkest";
282 NatUtil.addFlow(confTx, mdsalManager, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef,
283 NatConstants.SNAT_TRK_FLOW_PRIORITY, flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructionInfo);
287 protected void removeOutboundTblTrackEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx,
288 Uint64 dpnId, Uint32 routerId) throws ExecutionException, InterruptedException {
289 LOG.info("createOutboundTblTrackEntryForVxlanGre: Install Outbound tracking table flow on dpId {} for "
290 + "routerId {}", dpnId, routerId);
292 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId) + "trkest";
293 NatUtil.removeFlow(confTx, mdsalManager, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
297 protected void addOutboundTblEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, Uint64 dpnId,
298 Uint32 routerId, Uint32 extNetVpnId, List<ExternalIps> externalIps,
300 LOG.info("createOutboundTblEntryForVxlanGre: Install Outbound table flow on dpId {} for routerId {}", dpnId,
302 List<MatchInfoBase> matches = new ArrayList<>();
303 matches.add(MatchEthernetType.IPV4);
304 matches.add(new NxMatchCtState(TRACKED_NEW_CT_STATE, TRACKED_NEW_CT_MASK));
305 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId.longValue()),
306 MetaDataUtil.METADATA_MASK_VRFID));
307 if (externalIps.isEmpty()) {
308 LOG.error("createOutboundTblEntryForVxlanGre: No externalIP present for routerId {}",
312 //The logic now handle only one external IP per router, others if present will be ignored.
313 String externalIp = externalIps.get(0).getIpAddress();
314 List<ActionInfo> actionsInfos = new ArrayList<>();
315 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
316 .getVpnIdMetadata(extNetVpnId.longValue()));
317 actionsInfos.add(actionSetFieldMeta);
318 List<ActionNxConntrack.NxCtAction> ctActionsListCommit = new ArrayList<>();
319 int rangePresent = NxActionNatRangePresent.NXNATRANGEIPV4MIN.getIntValue();
320 int flags = NxActionNatFlags.NXNATFSRC.getIntValue();
321 ActionNxConntrack.NxCtAction nxCtActionCommit = new ActionNxConntrack.NxNat(0, flags, rangePresent,
322 IpPrefixOrAddressBuilder.getDefaultInstance(externalIp).getIpAddress(), null,0, 0);
323 ctActionsListCommit.add(nxCtActionCommit);
324 int ctCommitFlag = 1;
325 ActionNxConntrack actionNxConntrackSubmit = new ActionNxConntrack(ctCommitFlag, 0, elanId,
326 NwConstants.NAPT_PFIB_TABLE, ctActionsListCommit);
327 actionsInfos.add(actionNxConntrackSubmit);
328 List<InstructionInfo> instructions = new ArrayList<>();
329 instructions.add(new InstructionApplyActions(actionsInfos));
330 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
331 NatUtil.addFlow(confTx, mdsalManager, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef,
332 NatConstants.SNAT_NEW_FLOW_PRIORITY, flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
335 protected void removeOutboundTblEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, Uint64 dpnId,
336 Uint32 routerId, List<ExternalIps> externalIps)
337 throws ExecutionException, InterruptedException {
338 LOG.info("createOutboundTblEntryForVxlanGre: Install Outbound table flow on dpId {} for routerId {}", dpnId,
340 if (externalIps.isEmpty()) {
341 LOG.error("createOutboundTblEntryForVxlanGre: No externalIP present for routerId {}",
345 //The logic now handle only one external IP per router, others if present will be ignored.
346 String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
347 NatUtil.removeFlow(confTx, mdsalManager, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
350 protected void addNaptPfibFlowForVxlanGre(TypedWriteTransaction<Configuration> confTx, Routers routers,
351 Uint64 dpnId, Uint32 extNetVpnId) {
352 LOG.info("installNaptPfibFlowForVxlanGre: Install Napt preFibFlow on dpId {} with matching extNetVpnId {} "
353 + "for router {}", dpnId, extNetVpnId, routers.getRouterName());
354 List<MatchInfoBase> matches = new ArrayList<>();
355 matches.add(MatchEthernetType.IPV4);
356 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNetVpnId.longValue()),
357 MetaDataUtil.METADATA_MASK_VRFID));
358 ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
359 ArrayList<InstructionInfo> instructions = new ArrayList<>();
360 listActionInfo.add(new ActionNxLoadInPort(Uint64.ZERO));
361 listActionInfo.add(new ActionNxResubmit(NwConstants.L3_FIB_TABLE));
362 instructions.add(new InstructionApplyActions(listActionInfo));
363 String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, extNetVpnId);
364 NatUtil.addFlow(confTx, mdsalManager, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef,
365 NatConstants.SNAT_TRK_FLOW_PRIORITY, flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
368 protected void removeNaptPfibFlowForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
369 Uint64 dpnId, Uint32 extNetVpnId) throws ExecutionException, InterruptedException {
370 LOG.info("installNaptPfibFlowForVxlanGre: Install Napt preFibFlow on dpId {} with matching extNetVpnId {} "
371 + "for router {}", dpnId, extNetVpnId, routers.getRouterName());
372 String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, extNetVpnId);
373 NatUtil.removeFlow(confTx, mdsalManager, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef);
376 protected void addInboundEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, Uint64 dpnId,
377 Uint32 routerId, Uint32 extNeVpnId, List<ExternalIps> externalIps,
379 LOG.info("installInboundEntryForVxlanGre: Install Inbound table entry on dpId {} for routerId {}",
381 List<MatchInfoBase> matches = new ArrayList<>();
382 matches.add(MatchEthernetType.IPV4);
383 if (externalIps.isEmpty()) {
384 LOG.error("installInboundEntryForVxlanGre : createInboundTblEntry no externalIP present for routerId {}",
388 String externalIp = externalIps.get(0).getIpAddress();
389 matches.add(new MatchIpv4Destination(externalIp,"32"));
390 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNeVpnId.longValue()),
391 MetaDataUtil.METADATA_MASK_VRFID));
392 List<ActionInfo> actionsInfos = new ArrayList<>();
393 List<ActionNxConntrack.NxCtAction> ctActionsList = new ArrayList<>();
394 ActionNxConntrack.NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
395 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
396 .getVpnIdMetadata(routerId.longValue()));
397 actionsInfos.add(actionSetFieldMeta);
398 ctActionsList.add(nxCtAction);
399 ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
400 .NAPT_PFIB_TABLE,ctActionsList);
402 actionsInfos.add(actionNxConntrack);
403 List<InstructionInfo> instructions = new ArrayList<>();
404 instructions.add(new InstructionApplyActions(actionsInfos));
405 String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
406 NatUtil.addFlow(confTx, mdsalManager, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef,
407 NatConstants.DEFAULT_TS_FLOW_PRIORITY, flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
410 protected void removeInboundEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, Uint64 dpnId,
411 Uint32 routerId, List<ExternalIps> externalIps)
412 throws ExecutionException, InterruptedException {
413 LOG.info("removeInboundEntryForVxlanGre: remove Inbound table entry on dpId {} for routerId {}",
415 if (externalIps.isEmpty()) {
416 LOG.error("removeInboundEntryForVxlanGre : createInboundTblEntry no externalIP present for routerId {}",
421 String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
422 NatUtil.removeFlow(confTx, mdsalManager, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef);
425 protected void addTerminatingServiceTblEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx,
426 Uint64 dpnId, String routerName, Uint32 routerId, int elanId) {
427 LOG.info("installTerminatingServiceTblEntryForVxlanGre : creating entry for"
428 + "Terminating Service Table for switch {}, routerId {}", dpnId, routerId);
429 List<MatchInfo> matches = new ArrayList<>();
430 matches.add(MatchEthernetType.IPV4);
432 Uint64 tunnelId = Uint64.valueOf(routerId);
433 if (elanManager.isOpenStackVniSemanticsEnforced()) {
434 tunnelId = natOverVxlanUtil.getRouterVni(routerName, routerId);
436 matches.add(new MatchTunnelId(tunnelId));
438 List<ActionInfo> actionsInfos = new ArrayList<>();
439 List<NxCtAction> ctActionsList = new ArrayList<>();
440 NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
441 ctActionsList.add(nxCtAction);
442 ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
443 .OUTBOUND_NAPT_TABLE,ctActionsList);
444 ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
445 .getVpnIdMetadata(routerId.longValue()));
446 actionsInfos.add(actionSetFieldMeta);
447 actionsInfos.add(actionNxConntrack);
448 List<InstructionInfo> instructions = new ArrayList<>();
449 instructions.add(new InstructionApplyActions(actionsInfos));
450 String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId);
451 NatUtil.addFlow(confTx, mdsalManager, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef,
452 NatConstants.DEFAULT_TS_FLOW_PRIORITY, flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
456 protected void removeTerminatingServiceTblEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx,
457 Uint64 dpnId, Uint32 routerId) throws ExecutionException, InterruptedException {
458 LOG.info("removeTerminatingServiceTblEntryForVxlanGre : removing entry for"
459 + "Terminating Service Table for switch {}, routerId {}", dpnId, routerId);
461 String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId);
462 NatUtil.removeFlow(confTx, mdsalManager, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef);
467 protected void addSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, Uint64 dpnId, Uint32 routerId,
468 String routerName, Uint64 primarySwitchId) {
469 LOG.debug("addSnatMissEntry : Installing SNAT miss entry in switch {}", dpnId);
470 List<ActionInfo> listActionInfoPrimary = new ArrayList<>();
471 String ifNamePrimary = NatUtil.getTunnelInterfaceName(dpnId, primarySwitchId, itmManager);
472 List<BucketInfo> listBucketInfo = new ArrayList<>();
473 if (ifNamePrimary != null) {
474 LOG.debug("addSnatMissEntry : On Non- Napt switch , Primary Tunnel interface is {}", ifNamePrimary);
475 listActionInfoPrimary = NatUtil.getEgressActionsForInterface(odlInterfaceRpcService, itmManager,
476 interfaceManager, ifNamePrimary, routerId, true);
478 BucketInfo bucketPrimary = new BucketInfo(listActionInfoPrimary);
479 listBucketInfo.add(0, bucketPrimary);
480 LOG.debug("addSnatMissEntry : addSnatMissEntry called for dpnId {} with primaryBucket {} ", dpnId,
481 listBucketInfo.get(0));
482 // Install the select group
483 Uint32 groupId = NatUtil.getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME, getGroupIdKey(routerName));
484 if (groupId != NatConstants.INVALID_ID) {
485 GroupEntity groupEntity = MDSALUtil
486 .buildGroupEntity(dpnId, groupId.longValue(), routerName, GroupTypes.GroupAll,
488 LOG.debug("addSnatMissEntry : installing the SNAT to NAPT GroupEntity:{}", groupEntity);
489 mdsalManager.addGroup(confTx, groupEntity);
490 // Install miss entry pointing to group
492 "addSnatMissEntry : buildSnatFlowEntity is called for dpId {}, routerName {} and groupId {}",
493 dpnId, routerName, groupId);
494 List<MatchInfo> matches = new ArrayList<>();
495 matches.add(new MatchEthernetType(0x0800L));
496 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId.longValue()),
497 MetaDataUtil.METADATA_MASK_VRFID));
499 List<ActionInfo> actionsInfo = new ArrayList<>();
501 Uint64 tunnelId = Uint64.valueOf(routerId);
502 if (elanManager.isOpenStackVniSemanticsEnforced()) {
503 tunnelId = natOverVxlanUtil.getRouterVni(routerName, routerId);
506 actionsInfo.add(new ActionSetFieldTunnelId(tunnelId));
507 LOG.debug("addSnatMissEntry : Setting the tunnel to the list of action infos {}",
509 actionsInfo.add(new ActionGroup(groupId.longValue()));
510 List<InstructionInfo> instructions = new ArrayList<>();
511 instructions.add(new InstructionApplyActions(actionsInfo));
512 String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
513 NatUtil.addFlow(confTx, mdsalManager, dpnId, NwConstants.PSNAT_TABLE, flowRef,
514 NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef, NwConstants.COOKIE_SNAT_TABLE,
518 LOG.error("installSnatMissEntry: Unable to get groupId for router:{}", routerName);
523 protected void removeSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, Uint64 dpnId,
524 Uint32 routerId, String routerName)
525 throws ExecutionException, InterruptedException {
526 LOG.debug("installSnatMissEntry : Removing SNAT miss entry in switch {}", dpnId);
528 String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
529 NatUtil.removeFlow(confTx, mdsalManager, dpnId, NwConstants.PSNAT_TABLE, flowRef);