import java.util.Collections;
import java.util.List;
import java.util.concurrent.Future;
+import javax.inject.Inject;
+import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
import org.opendaylight.genius.mdsalutil.ActionInfo;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
import org.opendaylight.genius.mdsalutil.MatchInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+@Singleton
public class VpnFloatingIpHandler implements FloatingIPHandler {
private static final Logger LOG = LoggerFactory.getLogger(VpnFloatingIpHandler.class);
private final DataBroker dataBroker;
private final VpnRpcService vpnService;
private final IBgpManager bgpManager;
private final FibRpcService fibService;
- private final FloatingIPListener floatingIPListener;
private final IVpnManager vpnManager;
private final IFibManager fibManager;
private final OdlArputilService arpUtilService;
private final EvpnDnatFlowProgrammer evpnDnatFlowProgrammer;
private final INeutronVpnManager nvpnManager;
private final IdManagerService idManager;
+ private static final BigInteger COOKIE_TUNNEL = new BigInteger("9000000", 16);
+ private static final String FLOWID_PREFIX = "NAT.";
- static final BigInteger COOKIE_TUNNEL = new BigInteger("9000000", 16);
- static final String FLOWID_PREFIX = "NAT.";
-
+ @Inject
public VpnFloatingIpHandler(final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
final VpnRpcService vpnService,
final IBgpManager bgpManager,
final FibRpcService fibService,
- final FloatingIPListener floatingIPListener,
final IFibManager fibManager,
final OdlArputilService arputilService,
final IVpnManager vpnManager,
this.vpnService = vpnService;
this.bgpManager = bgpManager;
this.fibService = fibService;
- this.floatingIPListener = floatingIPListener;
this.fibManager = fibManager;
this.arpUtilService = arputilService;
this.vpnManager = vpnManager;
if (provType == null) {
return;
}
+ NatOverVxlanUtil.validateAndCreateVxlanVniPool(dataBroker, nvpnManager, idManager,
+ NatConstants.ODL_VNI_POOL_NAME);
if (provType == ProviderTypes.VXLAN) {
Uuid floatingIpInterface = NatEvpnUtil.getFloatingIpInterfaceIdFromFloatingIpId(dataBroker, floatingIpId);
evpnDnatFlowProgrammer.onAddFloatingIp(dpnId, routerId, vpnName, internalIp, externalIp, networkId,
}
return;
}
-
- if (nvpnManager.getEnforceOpenstackSemanticsConfig()) {
- NatOverVxlanUtil.validateAndCreateVxlanVniPool(dataBroker, nvpnManager,
- idManager, NatConstants.ODL_VNI_POOL_NAME);
- }
-
GenerateVpnLabelInput labelInput = new GenerateVpnLabelInputBuilder().setVpnName(vpnName)
.setIpPrefix(externalIp).build();
Future<RpcResult<GenerateVpnLabelOutput>> labelFuture = vpnService.generateVpnLabel(labelInput);
- ListenableFuture<RpcResult<Void>> future = Futures.transform(JdkFutureAdapters.listenInPoolThread(labelFuture),
- (AsyncFunction<RpcResult<GenerateVpnLabelOutput>, RpcResult<Void>>) result -> {
+ ListenableFuture<RpcResult<Void>> future = Futures.transformAsync(
+ JdkFutureAdapters.listenInPoolThread(labelFuture),
+ (AsyncFunction<RpcResult<GenerateVpnLabelOutput>, RpcResult<Void>>) result -> {
if (result.isSuccessful()) {
GenerateVpnLabelOutput output = result.getResult();
long label = output.getLabel();
LOG.debug("Generated label {} for prefix {}", label, externalIp);
- floatingIPListener.updateOperationalDS(routerId, interfaceName, label, internalIp, externalIp);
+ FloatingIPListener.updateOperationalDS(dataBroker, routerId, interfaceName, label,
+ internalIp, externalIp);
//Inform BGP
long l3vni = 0;
- if (nvpnManager.getEnforceOpenstackSemanticsConfig()) {
+ if (elanService.isOpenStackVniSemanticsEnforced()) {
l3vni = NatOverVxlanUtil.getInternetVpnVni(idManager, vpnName, l3vni).longValue();
}
+ String fibExternalIp = NatUtil.validateAndAddNetworkMask(externalIp);
NatUtil.addPrefixToBGP(dataBroker, bgpManager, fibManager, vpnName, rd, subnetId,
- externalIp + "/32", nextHopIp, networkId.getValue(), floatingIpPortMacAddress,
+ fibExternalIp, nextHopIp, networkId.getValue(), floatingIpPortMacAddress,
label, l3vni, LOG, RouteOrigin.STATIC, dpnId);
List<Instruction> instructions = new ArrayList<>();
customInstructions.add(new InstructionApplyActions(actionInfoFib).buildInstruction(0));
customInstructions.add(new InstructionGotoTable(NwConstants.PDNAT_TABLE).buildInstruction(1));
- makeLFibTableEntry(dpnId, label, NwConstants.PDNAT_TABLE);
+ makeLFibTableEntry(dpnId, label, floatingIpPortMacAddress, NwConstants.PDNAT_TABLE);
CreateFibEntryInput input = new CreateFibEntryInputBuilder().setVpnName(vpnName)
.setSourceDpid(dpnId).setInstruction(customInstructions)
- .setIpAddress(externalIp + "/32").setServiceId(label)
+ .setIpAddress(fibExternalIp).setServiceId(label)
+ .setIpAddressSource(CreateFibEntryInput.IpAddressSource.FloatingIP)
.setInstruction(customInstructions).build();
//Future<RpcResult<java.lang.Void>> createFibEntry(CreateFibEntryInput input);
Future<RpcResult<Void>> future1 = fibService.createFibEntry(input);
String floatingIpPortMacAddress = NatUtil.getFloatingIpPortMacFromFloatingIpId(dataBroker, floatingIpId);
if (floatingIpPortMacAddress != null) {
WriteTransaction writeTx = dataBroker.newWriteOnlyTransaction();
- vpnManager.setupSubnetMacIntoVpnInstance(vpnName, subnetId.getValue(), floatingIpPortMacAddress,
+ String networkVpnName = NatUtil.getAssociatedVPN(dataBroker, networkId, LOG);
+ vpnManager.setupSubnetMacIntoVpnInstance(networkVpnName, subnetId.getValue(), floatingIpPortMacAddress,
dpnId, writeTx, NwConstants.DEL_FLOW);
vpnManager.setupArpResponderFlowsToExternalNetworkIps(routerId, Collections.singletonList(externalIp),
floatingIpPortMacAddress, dpnId, networkId, writeTx, NwConstants.DEL_FLOW);
if (provType == ProviderTypes.VXLAN) {
Uuid floatingIpInterface = NatEvpnUtil.getFloatingIpInterfaceIdFromFloatingIpId(dataBroker, floatingIpId);
evpnDnatFlowProgrammer.onRemoveFloatingIp(dpnId, vpnName, externalIp, floatingIpInterface.getValue(),
- floatingIpPortMacAddress);
+ floatingIpPortMacAddress, routerId);
return;
}
cleanupFibEntries(dpnId, vpnName, externalIp, label);
final long label) {
//Remove Prefix from BGP
String rd = NatUtil.getVpnRd(dataBroker, vpnName);
- NatUtil.removePrefixFromBGP(dataBroker, bgpManager, fibManager, rd, externalIp + "/32", vpnName, LOG);
+ String fibExternalIp = NatUtil.validateAndAddNetworkMask(externalIp);
+ NatUtil.removePrefixFromBGP(dataBroker, bgpManager, fibManager, rd, fibExternalIp, vpnName, LOG);
//Remove custom FIB routes
//Future<RpcResult<java.lang.Void>> removeFibEntry(RemoveFibEntryInput input);
RemoveFibEntryInput input = new RemoveFibEntryInputBuilder().setVpnName(vpnName)
- .setSourceDpid(dpnId).setIpAddress(externalIp + "/32").setServiceId(label).build();
+ .setSourceDpid(dpnId).setIpAddress(fibExternalIp).setServiceId(label)
+ .setIpAddressSource(RemoveFibEntryInput.IpAddressSource.FloatingIP).build();
Future<RpcResult<Void>> future = fibService.removeFibEntry(input);
- ListenableFuture<RpcResult<Void>> labelFuture = Futures.transform(JdkFutureAdapters.listenInPoolThread(future),
- (AsyncFunction<RpcResult<Void>, RpcResult<Void>>) result -> {
+ ListenableFuture<RpcResult<Void>> labelFuture = Futures.transformAsync(
+ JdkFutureAdapters.listenInPoolThread(future),
+ (AsyncFunction<RpcResult<Void>, RpcResult<Void>>) result -> {
//Release label
if (result.isSuccessful()) {
- removeTunnelTableEntry(dpnId, label);
+ /* check if any floating IP information is available in vpn-to-dpn-list for given dpn id. If exist any
+ * floating IP then do not remove INTERNAL_TUNNEL_TABLE (table=36) -> PDNAT_TABLE (table=25) flow entry
+ */
+ Boolean removeTunnelFlow = Boolean.TRUE;
+ if (elanService.isOpenStackVniSemanticsEnforced()) {
+ if (NatUtil.isFloatingIpPresentForDpn(dataBroker, dpnId, rd, vpnName, externalIp, false)) {
+ removeTunnelFlow = Boolean.FALSE;
+ }
+ }
+ if (removeTunnelFlow) {
+ removeTunnelTableEntry(dpnId, label);
+ }
removeLFibTableEntry(dpnId, label);
RemoveVpnLabelInput labelInput = new RemoveVpnLabelInputBuilder()
.setVpnName(vpnName).setIpPrefix(externalIp).build();
// Increased the 36->25 flow priority. If SNAT is also configured on the same
// DPN, then the traffic will be hijacked to DNAT and if there are no DNAT match,
// then handled back to using using flow 25->44(which will be installed as part of SNAT)
- if (nvpnManager.getEnforceOpenstackSemanticsConfig()) {
+ if (elanService.isOpenStackVniSemanticsEnforced()) {
mkMatches.add(new MatchTunnelId(NatOverVxlanUtil.getInternetVpnVni(idManager, vpnName, serviceId)));
flowPriority = 6;
} else {
mdsalManager.installFlow(dpnId, terminatingServiceTableFlowEntity);
}
- private void makeLFibTableEntry(BigInteger dpId, long serviceId, short tableId) {
+ private void makeLFibTableEntry(BigInteger dpId, long serviceId, String floatingIpPortMacAddress, short tableId) {
List<MatchInfo> matches = new ArrayList<>();
matches.add(MatchEthernetType.MPLS_UNICAST);
matches.add(new MatchMplsLabel(serviceId));
List<Instruction> instructions = new ArrayList<>();
List<ActionInfo> actionsInfos = new ArrayList<>();
actionsInfos.add(new ActionPopMpls());
+ actionsInfos.add(new ActionSetFieldEthernetDestination(new MacAddress(floatingIpPortMacAddress)));
Instruction writeInstruction = new InstructionApplyActions(actionsInfos).buildInstruction(0);
instructions.add(writeInstruction);
instructions.add(new InstructionGotoTable(tableId).buildInstruction(1));
InstanceIdentifier id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
try {
Optional<FloatingIpIdToPortMapping> optFloatingIpIdToPortMapping =
- NatUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
+ SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
+ LogicalDatastoreType.CONFIGURATION, id);
if (optFloatingIpIdToPortMapping.isPresent() && optFloatingIpIdToPortMapping.get().isFloatingIpDeleted()) {
LOG.debug("Deleting floating IP UUID {} to Floating IP neutron port mapping from Floating "
+ "IP Port Info Config DS", floatingIpId.getValue());