import com.google.common.base.Optional;
import java.math.BigInteger;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
-import javax.annotation.Nonnull;
import javax.inject.Inject;
import javax.inject.Singleton;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
import org.opendaylight.genius.mdsalutil.MetaDataUtil;
import org.opendaylight.genius.mdsalutil.NwConstants;
import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
-import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldTunnelId;
import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
private final SnatServiceManager natServiceManager;
private final NatMode natMode;
private final IInterfaceManager interfaceManager;
+ private final NatOverVxlanUtil natOverVxlanUtil;
private volatile Collection<String> externalIpsCache;
final SnatServiceManager natServiceManager,
final NatserviceConfig config,
final NaptEventHandler naptEventHandler,
- final IInterfaceManager interfaceManager) {
+ final IInterfaceManager interfaceManager,
+ final NatOverVxlanUtil natOverVxlanUtil) {
this.dataBroker = dataBroker;
this.mdsalManager = mdsalManager;
this.externalRouterListener = externalRouterListener;
} else {
this.natMode = NatMode.Controller;
}
+ this.natOverVxlanUtil = natOverVxlanUtil;
}
protected void removeSnatFlowsInOldNaptSwitch(String routerName, Long routerId, BigInteger naptSwitch,
- Map<String, Long> externalIpmap,
+ @Nullable Map<String, Long> externalIpmap, String externalVpnName,
TypedReadWriteTransaction<Configuration> confTx)
throws ExecutionException, InterruptedException {
//remove SNAT flows in old NAPT SWITCH
- Uuid networkId = NatUtil.getNetworkIdFromRouterName(dataBroker, routerName);
- String vpnName = getExtNetworkVpnName(routerName, networkId);
+ Uuid extNetworkId = NatUtil.getNetworkIdFromRouterName(dataBroker, routerName);
+ String vpnName = getExtNetworkVpnName(routerName, extNetworkId);
if (vpnName == null) {
LOG.error("removeSnatFlowsInOldNaptSwitch : Vpn is not associated to externalN/w of router {}",
routerName);
return;
}
- ProviderTypes extNwProvType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker, routerName, networkId);
+ ProviderTypes extNwProvType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker, routerName, extNetworkId);
if (extNwProvType == null) {
LOG.error("removeSnatFlowsInOldNaptSwitch : Unable to retrieve the External Network Provider Type "
+ "for Router {}", routerName);
evpnNaptSwitchHA.evpnRemoveSnatFlowsInOldNaptSwitch(routerName, routerId, vpnName, naptSwitch, confTx);
} else {
//Remove the Terminating Service table entry which forwards the packet to Outbound NAPT Table
- long tunnelId = NatUtil.getTunnelIdForNonNaptToNaptFlow(dataBroker, elanManager, idManager, routerId,
- routerName);
+ long tunnelId = NatUtil.getTunnelIdForNonNaptToNaptFlow(dataBroker, natOverVxlanUtil, elanManager,
+ idManager, routerId, routerName);
String tsFlowRef = externalRouterListener.getFlowRefTs(naptSwitch, NwConstants.INTERNAL_TUNNEL_TABLE,
tunnelId);
FlowEntity tsNatFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NwConstants.INTERNAL_TUNNEL_TABLE,
// Remove the NAPT_PFIB_TABLE(47) flow entry forwards the packet to Fib Table for outbound traffic
// matching on the vpn ID.
boolean switchSharedByRouters = false;
- Uuid extNetworkId = NatUtil.getNetworkIdFromRouterName(dataBroker, routerName);
if (extNetworkId != null && !NatUtil.checkForRoutersWithSameExtNetAndNaptSwitch(
- dataBroker, networkId, routerName, naptSwitch)) {
+ dataBroker, extNetworkId, routerName, naptSwitch)) {
List<String> routerNamesAssociated = getRouterIdsForExtNetwork(extNetworkId);
for (String routerNameAssociated : routerNamesAssociated) {
if (!routerNameAssociated.equals(routerName)) {
}
}
if (!switchSharedByRouters) {
- Long vpnId = getVpnIdForRouter(routerId, extNetworkId);
+ Long vpnId = NatUtil.getVpnId(dataBroker,externalVpnName);
if (vpnId != NatConstants.INVALID_ID) {
String naptFibflowRef =
externalRouterListener.getFlowRefTs(naptSwitch, NwConstants.NAPT_PFIB_TABLE, vpnId);
for (Entry<String, Long> entry : externalIpmap.entrySet()) {
String externalIp = entry.getKey();
Long label = entry.getValue();
- externalRouterListener.delFibTsAndReverseTraffic(naptSwitch, routerId, externalIp, vpnName,
+ externalRouterListener.delFibTsAndReverseTraffic(naptSwitch, routerName, routerId, externalIp, vpnName,
extNetworkId, label, gwMacAddress, true, confTx);
LOG.debug("removeSnatFlowsInOldNaptSwitch : Successfully removed fib entries in old naptswitch {} "
+ "for router {} and externalIps {} label {}", naptSwitch, routerId, externalIp, label);
}
} else {
List<String> externalIps = NatUtil.getExternalIpsForRouter(dataBroker, routerName);
- if (networkId != null) {
- externalRouterListener.clearFibTsAndReverseTraffic(naptSwitch, routerId, networkId,
+ if (extNetworkId != null) {
+ externalRouterListener.clearFibTsAndReverseTraffic(naptSwitch, routerId, extNetworkId,
externalIps, null, gwMacAddress, confTx);
LOG.debug(
"removeSnatFlowsInOldNaptSwitch : Successfully removed fib entries in old naptswitch {} for "
- + "router {} with networkId {} and externalIps {}", naptSwitch, routerId, networkId,
+ + "router {} with networkId {} and externalIps {}", naptSwitch, routerId, extNetworkId,
externalIps);
} else {
LOG.debug("removeSnatFlowsInOldNaptSwitch : External network not associated to router {}",
LOG.debug("removeSnatFlowsInOldNaptSwitch : No {} session associated to router {},"
+ "no flows need to be removed in oldNaptSwitch {}",
intextIpProtocolType.getProtocol(), routerId, naptSwitch);
- break;
+ continue;
}
+ String protocol = intextIpProtocolType.getProtocol().name();
List<IpPortMap> ipPortMaps = intextIpProtocolType.getIpPortMap();
for (IpPortMap ipPortMap : ipPortMaps) {
String ipPortInternal = ipPortMap.getIpPortInternal();
//Build and remove flow in outbound NAPT table
String switchFlowRef =
NatUtil.getNaptFlowRef(naptSwitch, NwConstants.OUTBOUND_NAPT_TABLE, String.valueOf(routerId),
- internalIp, Integer.parseInt(internalPort));
+ internalIp, Integer.parseInt(internalPort), protocol);
FlowEntity outboundNaptFlowEntity =
NatUtil.buildFlowEntity(naptSwitch, NwConstants.OUTBOUND_NAPT_TABLE,
cookieSnatFlow, switchFlowRef);
+ "with the DPN ID {} and router ID {}", NwConstants.OUTBOUND_NAPT_TABLE, naptSwitch, routerId);
mdsalManager.removeFlow(confTx, outboundNaptFlowEntity);
- IpPortExternal ipPortExternal = ipPortMap.getIpPortExternal();
- if (ipPortExternal == null) {
- LOG.debug(
- "removeSnatFlowsInOldNaptSwitch : External Ipport mapping not found for internalIp {} "
- + "with port {} for router {}", internalIp, internalPort, routerId);
- continue;
- }
- String externalIp = ipPortExternal.getIpAddress();
- int externalPort = ipPortExternal.getPortNum();
-
//Build and remove flow in inbound NAPT table
switchFlowRef =
NatUtil.getNaptFlowRef(naptSwitch, NwConstants.INBOUND_NAPT_TABLE, String.valueOf(routerId),
- externalIp, externalPort);
+ internalIp, Integer.parseInt(internalPort), protocol);
FlowEntity inboundNaptFlowEntity =
NatUtil.buildFlowEntity(naptSwitch, NwConstants.INBOUND_NAPT_TABLE,
cookieSnatFlow, switchFlowRef);
}
}
- @Nonnull
+ @NonNull
private List<String> getRouterIdsForExtNetwork(Uuid extNetworkId) {
List<String> routerUuidsAsString = new ArrayList<>();
InstanceIdentifier<Networks> extNetwork = InstanceIdentifier.builder(ExternalNetworks.class)
Uuid networkId = NatUtil.getNetworkIdFromRouterName(dataBroker, routerName);
String vpnName = getExtNetworkVpnName(routerName, networkId);
//elect a new NaptSwitch
- naptSwitch = naptSwitchSelector.selectNewNAPTSwitch(routerName);
+ naptSwitch = naptSwitchSelector.selectNewNAPTSwitch(routerName, Arrays.asList(naptSwitch));
if (natMode == NatMode.Conntrack) {
Routers extRouters = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
- natServiceManager.notify(confTx, extRouters, dpnId, dpnId, SnatServiceManager.Action.SNAT_ALL_SWITCH_DISBL);
- natServiceManager.notify(confTx, extRouters, naptSwitch, naptSwitch,
- SnatServiceManager.Action.SNAT_ALL_SWITCH_ENBL);
+ natServiceManager.notify(confTx, extRouters, null, dpnId, dpnId,
+ SnatServiceManager.Action.CNT_ROUTER_ALL_SWITCH_DISBL);
+ if (extRouters.isEnableSnat()) {
+ natServiceManager.notify(confTx, extRouters, null, dpnId, dpnId,
+ SnatServiceManager.Action.SNAT_ALL_SWITCH_DISBL);
+ }
+ natServiceManager.notify(confTx, extRouters, null, naptSwitch, naptSwitch,
+ SnatServiceManager.Action.CNT_ROUTER_ALL_SWITCH_ENBL);
+ if (extRouters.isEnableSnat()) {
+ natServiceManager.notify(confTx, extRouters, null, naptSwitch, naptSwitch,
+ SnatServiceManager.Action.SNAT_ALL_SWITCH_ENBL);
+ }
} else {
if (naptSwitch.equals(BigInteger.ZERO)) {
LOG.warn("isNaptSwitchDown : No napt switch is elected since all the switches for router {}"
mdsalManager.addFlow(confTx, flowEntity);
}
- installSnatFlows(routerName, routerId, naptSwitch, routerVpnId, confTx);
+ installSnatFlows(routerName, routerId, naptSwitch, routerVpnId, networkId, vpnName, confTx);
boolean flowInstalledStatus = handleNatFlowsInNewNaptSwitch(routerName, routerId, dpnId, naptSwitch,
routerVpnId, networkId);
}
//remove group in new naptswitch, coz this switch acted previously as ordinary switch
- long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(routerName), idManager);
- try {
- LOG.info("isNaptSwitchDown : Removing NAPT Group in new naptSwitch {}", naptSwitch);
- mdsalManager.removeGroup(confTx, naptSwitch, groupId);
- } catch (Exception ex) {
- LOG.error("isNaptSwitchDown : Failed to remove group in new naptSwitch {}", naptSwitch, ex);
+ long groupId = NatUtil.getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME,
+ NatUtil.getGroupIdKey(routerName));
+ if (groupId != NatConstants.INVALID_ID) {
+ try {
+ LOG.info("isNaptSwitchDown : Removing NAPT Group in new naptSwitch {}",
+ naptSwitch);
+ mdsalManager.removeGroup(confTx, naptSwitch, groupId);
+ } catch (Exception ex) {
+ LOG.error("isNaptSwitchDown : Failed to remove group in new naptSwitch {}",
+ naptSwitch, ex);
+ }
+ } else {
+ LOG.error("NAT Service : Unable to obtain groupId for router:{}", routerName);
}
}
return true;
}
+ @Nullable
private String getExtNetworkVpnName(String routerName, Uuid networkId) {
if (networkId == null) {
LOG.error("getExtNetworkVpnName : networkId is null for the router ID {}", routerName);
LOG.debug("updateNaptSwitchBucketStatus : Updating SNAT_TABLE missentry for DpnId {} "
+ "which is not naptSwitch for router {}", dpn, routerName);
List<BucketInfo> bucketInfoList = handleGroupInNeighborSwitches(dpn, routerName, routerId, naptSwitch);
+ if (bucketInfoList.isEmpty()) {
+ LOG.error("Failed to populate bucketInfo for non-napt switch {} whose naptSwitch:{} for router:{}",
+ dpn,naptSwitch,routerName);
+ continue;
+ }
modifySnatGroupEntry(dpn, bucketInfoList, routerName);
+ externalRouterListener.installSnatMissEntry(dpn, bucketInfoList, routerName, routerId);
}
}
}
}
Long bgpVpnId;
if (routerId.equals(routerVpnId)) {
- bgpVpnId = NatConstants.INVALID_ID;
+ bgpVpnId = Long.valueOf(NatConstants.INVALID_ID);
} else {
bgpVpnId = routerVpnId;
}
} catch (Exception ex) {
LOG.error("getVpnIdForRouter : Exception while retrieving vpnId for router {}", routerId, ex);
}
- return NatConstants.INVALID_ID;
+ return Long.valueOf(NatConstants.INVALID_ID);
}
- public List<BucketInfo> handleGroupInPrimarySwitch() {
- List<BucketInfo> listBucketInfo = new ArrayList<>();
- List<ActionInfo> listActionInfoPrimary = new ArrayList<>();
- listActionInfoPrimary.add(new ActionNxResubmit(NwConstants.INTERNAL_TUNNEL_TABLE));
- BucketInfo bucketPrimary = new BucketInfo(listActionInfoPrimary);
- listBucketInfo.add(bucketPrimary);
- return listBucketInfo;
- }
-
- @Nonnull
+ @NonNull
public List<BucketInfo> handleGroupInNeighborSwitches(BigInteger dpnId, String routerName, long routerId,
BigInteger naptSwitch) {
List<BucketInfo> listBucketInfo = new ArrayList<>();
protected void installSnatGroupEntry(BigInteger dpnId, List<BucketInfo> bucketInfo, String routerName) {
GroupEntity groupEntity = null;
try {
- long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(routerName), idManager);
- LOG.debug("installSnatGroupEntry : install SnatMissEntry for groupId {} for dpnId {} for router {}",
+ long groupId = NatUtil.getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME,
+ NatUtil.getGroupIdKey(routerName));
+ if (groupId != NatConstants.INVALID_ID) {
+ LOG.debug(
+ "installSnatGroupEntry : install SnatMissEntry for groupId {} for dpnId {} for router {}",
groupId, dpnId, routerName);
- groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName,
- GroupTypes.GroupAll, bucketInfo);
- mdsalManager.syncInstallGroup(groupEntity);
- LOG.debug("installSnatGroupEntry : installed the SNAT to NAPT GroupEntity:{}", groupEntity);
+ groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName,
+ GroupTypes.GroupAll, bucketInfo);
+ mdsalManager.syncInstallGroup(groupEntity);
+ LOG.debug("installSnatGroupEntry : installed the SNAT to NAPT GroupEntity:{}",
+ groupEntity);
+ } else {
+ LOG.error("installSnatGroupEntry: Unable to obtain groupId for router:{}", routerName);
+ }
} catch (Exception ex) {
LOG.error("installSnatGroupEntry : Failed to install group for groupEntity {}", groupEntity, ex);
}
LOG.debug("modifySnatGroupEntry : modified SnatMissEntry for dpnId {} of router {}", dpnId, routerName);
}
+ @Nullable
protected String getTunnelInterfaceName(BigInteger srcDpId, BigInteger dstDpId) {
Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
RpcResult<GetTunnelInterfaceNameOutput> rpcResult;
if (addordel == NatConstants.ADD_FLOW) {
List<ActionInfo> actionsInfo = new ArrayList<>();
- long tunnelId = NatUtil.getTunnelIdForNonNaptToNaptFlow(dataBroker, elanManager, idManager, routerVpnId,
- routerName);
+ long tunnelId = NatUtil.getTunnelIdForNonNaptToNaptFlow(dataBroker, natOverVxlanUtil, elanManager,
+ idManager, routerVpnId, routerName);
actionsInfo.add(new ActionSetFieldTunnelId(BigInteger.valueOf(tunnelId)));
LOG.debug("buildSnatFlowEntity : Setting the tunnel to the list of action infos {}", actionsInfo);
actionsInfo.add(new ActionGroup(groupId));
}
protected void installSnatFlows(String routerName, Long routerId, BigInteger naptSwitch, Long routerVpnId,
- TypedReadWriteTransaction<Configuration> confTx) {
+ Uuid networkId, String vpnName, TypedReadWriteTransaction<Configuration> confTx) {
if (routerId.equals(routerVpnId)) {
LOG.debug("installSnatFlows : Installing flows for router with internalvpnId");
externalRouterListener.installNaptPfibEntryWithBgpVpn(naptSwitch, routerId, routerVpnId, confTx);
}
- Uuid networkId = NatUtil.getNetworkIdFromRouterName(dataBroker, routerName);
- String vpnName = getExtNetworkVpnName(routerName, networkId);
if (vpnName != null) {
//NAPT PFIB point to FIB table for outbound traffic
long vpnId = NatUtil.getVpnId(dataBroker, vpnName);
- boolean shouldInstallNaptPfibWithExtNetworkVpnId = true;
- Collection<Uuid> externalSubnetIds = NatUtil.getExternalSubnetIdsForRouter(dataBroker, routerName);
- if (!externalSubnetIds.isEmpty()) {
- //NAPT PFIB point to FIB table for outbound traffic - using external subnetID as vpnID.
- for (Uuid externalSubnetId : externalSubnetIds) {
- long externalSubnetVpnId = NatUtil.getExternalSubnetVpnId(dataBroker, externalSubnetId);
- if (externalSubnetVpnId != NatConstants.INVALID_ID) {
- shouldInstallNaptPfibWithExtNetworkVpnId = false;
- LOG.debug("installSnatFlows : installNaptPfibEntry fin naptswitch with dpnId {} for "
- + "BgpVpnId {}", naptSwitch, externalSubnetVpnId);
- externalRouterListener.installNaptPfibEntry(naptSwitch, externalSubnetVpnId, confTx);
+ if (vpnName.equals(networkId.getValue())) {
+ // below condition valid only for flat/vlan use-case
+ boolean shouldInstallNaptPfibWithExtNetworkVpnId = true;
+ Collection<Uuid> externalSubnetIds = NatUtil
+ .getExternalSubnetIdsForRouter(dataBroker, routerName);
+ if (!externalSubnetIds.isEmpty()) {
+ //NAPT PFIB point to FIB table for outbound traffic - using external subnetID as vpnID.
+ for (Uuid externalSubnetId : externalSubnetIds) {
+ long externalSubnetVpnId = NatUtil
+ .getExternalSubnetVpnId(dataBroker, externalSubnetId);
+ if (externalSubnetVpnId != NatConstants.INVALID_ID) {
+ shouldInstallNaptPfibWithExtNetworkVpnId = false;
+ LOG.debug(
+ "installSnatFlows : installNaptPfibEntry fin naptswitch with dpnId {} for "
+ + "BgpVpnId {}", naptSwitch, externalSubnetVpnId);
+ externalRouterListener
+ .installNaptPfibEntry(naptSwitch, externalSubnetVpnId, confTx);
+ }
}
}
+ if (vpnId != NatConstants.INVALID_ID && shouldInstallNaptPfibWithExtNetworkVpnId) {
+ //NAPT PFIB table point to FIB table for outbound traffic - using external networkID as vpnID.
+ LOG.debug(
+ "installSnatFlows : installNaptPfibEntry fin naptswitch with dpnId {} for "
+ + "BgpVpnId {}", naptSwitch, vpnId);
+ externalRouterListener.installNaptPfibEntry(naptSwitch, vpnId, confTx);
+ } else if (vpnId != NatConstants.INVALID_ID) {
+ LOG.debug("installSnatFlows : Associated BgpvpnId not found for router {}",
+ routerId);
+ }
}
- if (vpnId != NatConstants.INVALID_ID && shouldInstallNaptPfibWithExtNetworkVpnId) {
- //NAPT PFIB table point to FIB table for outbound traffic - using external networkID as vpnID.
- LOG.debug("installSnatFlows : installNaptPfibEntry fin naptswitch with dpnId {} for "
- + "BgpVpnId {}", naptSwitch, vpnId);
- externalRouterListener.installNaptPfibEntry(naptSwitch, vpnId, confTx);
- } else if (vpnId != NatConstants.INVALID_ID) {
- LOG.debug("installSnatFlows : Associated BgpvpnId not found for router {}", routerId);
- }
-
//Install Fib entries for ExternalIps & program 36 -> 44
Collection<String> externalIps = NatUtil.getExternalIpsForRouter(dataBroker, routerId);
String rd = NatUtil.getVpnRd(dataBroker, vpnName);
if (extNwProvType == ProviderTypes.VXLAN) {
for (String externalIp : removedExternalIps) {
externalRouterListener.clearBgpRoutes(externalIp, vpnName);
- externalRouterListener.delFibTsAndReverseTraffic(naptSwitch, routerId, externalIp, vpnName,
- networkId, NatConstants.DEFAULT_LABEL_VALUE, gwMacAddress, true, confTx);
+ externalRouterListener.delFibTsAndReverseTraffic(naptSwitch, routerName, routerId, externalIp,
+ vpnName, networkId, NatConstants.DEFAULT_LABEL_VALUE, gwMacAddress, true, confTx);
LOG.debug("bestEffortDeletion : Successfully removed fib entry for externalIp {} for routerId {} "
+ "on NAPT switch {} ", externalIp, routerId, naptSwitch);
}
continue;
}
externalRouterListener.clearBgpRoutes(externalIp, vpnName);
- externalRouterListener.delFibTsAndReverseTraffic(naptSwitch, routerId, externalIp, vpnName,
- networkId, label, gwMacAddress, true, confTx);
+ externalRouterListener.delFibTsAndReverseTraffic(naptSwitch, routerName, routerId, externalIp,
+ vpnName, networkId, label, gwMacAddress, true, confTx);
LOG.debug("bestEffortDeletion : Successfully removed fib entries in switch {} for router {} "
+ "and externalIps {}", naptSwitch, routerId, externalIp);
}