use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance in project netvirt by opendaylight.
the class FloatingIPListener method createNATFlowEntries.
void createNATFlowEntries(Uint64 dpnId, String interfaceName, String routerName, Uuid externalNetworkId, InternalToExternalPortMap mapping, TypedReadWriteTransaction<Configuration> confTx) throws ExecutionException, InterruptedException {
Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
if (routerId == NatConstants.INVALID_ID) {
LOG.error("createNATFlowEntries : Could not retrieve router id for {} to create NAT Flow entries", routerName);
return;
}
// Check if the router to vpn association is present
Uint32 associatedVpnId = NatUtil.getAssociatedVpn(dataBroker, routerName);
if (associatedVpnId == NatConstants.INVALID_ID) {
LOG.debug("createNATFlowEntries : Router {} is not assicated with any BGP VPN instance", routerName);
} else {
LOG.debug("createNATFlowEntries : Router {} is associated with VPN Instance with Id {}", routerName, associatedVpnId);
// routerId = associatedVpnId;
}
Uuid vpnUuid = getVpnUuid(externalNetworkId, mapping.getExternalId());
LOG.trace("createNATFlowEntries : vpnUuid {} for External Network {}", vpnUuid, externalNetworkId);
if (vpnUuid == null) {
LOG.error("createNATFlowEntries : No vpnUuid associated with Ext nw {}. Unable to create SNAT table entry" + " for fixed ip {}", externalNetworkId, mapping.getInternalIp());
return;
}
VpnInstance vpnInstance = NatUtil.getVpnIdToVpnInstance(dataBroker, vpnUuid.getValue());
if (vpnInstance == null || vpnInstance.getVpnId() == null) {
LOG.error("createNATFlowEntries: VpnInstance associated with Ext nw {}. Unable to create SNAT table entry" + " for fixed ip {}", externalNetworkId, mapping.getInternalIp());
return;
}
// Install the DNAT default FIB flow L3_FIB_TABLE (21) -> PSNAT_TABLE (26) if SNAT is disabled
boolean isSnatEnabled = NatUtil.isSnatEnabledForRouterId(dataBroker, routerName);
if (!isSnatEnabled) {
addOrDelDefaultFibRouteForDnat(dpnId, routerName, routerId, confTx, true);
}
// Create the DNAT and SNAT table entries
Uint32 vpnId = vpnInstance.getVpnId();
String vrfId = vpnInstance.getVrfId();
createDNATTblEntry(dpnId, mapping, routerId, associatedVpnId, confTx);
createSNATTblEntry(dpnId, mapping, vpnId, routerId, associatedVpnId, externalNetworkId, confTx);
floatingIPHandler.onAddFloatingIp(dpnId, routerName, routerId, externalNetworkId, interfaceName, mapping, vrfId, confTx);
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance in project netvirt by opendaylight.
the class FloatingIPListener method removeNATFlowEntries.
void removeNATFlowEntries(String interfaceName, final InternalToExternalPortMap mapping, InstanceIdentifier<RouterPorts> portIid, final String routerName, @Nullable Uint64 dpnId, TypedReadWriteTransaction<Configuration> removeFlowInvTx) throws ExecutionException, InterruptedException {
Uuid extNwId = getExtNetworkId(portIid, LogicalDatastoreType.OPERATIONAL);
if (extNwId == null) {
LOG.error("removeNATFlowEntries : External network associated with interface {} could not be retrieved", interfaceName);
return;
}
// For FLAT/VLAN Networks, get the DPN with provider_mappings for external network.
if (dpnId == null) {
dpnId = getAssociatedDpnWithExternalInterface(routerName, extNwId, NatUtil.getDpnForInterface(interfaceManager, interfaceName), interfaceName);
if (dpnId == null || dpnId.equals(Uint64.ZERO)) {
LOG.warn("removeNATFlowEntries: Abort processing Floating ip configuration. No DPN for port: {}", interfaceName);
return;
}
}
Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
if (routerId == NatConstants.INVALID_ID) {
LOG.error("removeNATFlowEntries : Could not retrieve router id for {} to remove NAT Flow entries", routerName);
return;
}
String internalIp = mapping.getInternalIp();
String externalIp = mapping.getExternalIp();
// Delete the DNAT and SNAT table entries
removeDNATTblEntry(dpnId, internalIp, externalIp, routerId, removeFlowInvTx);
Uuid vpnUuid = getVpnUuid(extNwId, mapping.getExternalId());
if (vpnUuid == null) {
LOG.error("removeNATFlowEntries : No VPN associated with Ext nw {}. Unable to remove SNAT table entry " + "for fixed ip {}", extNwId, mapping.getInternalIp());
return;
}
VpnInstance vpnInstance = NatUtil.getVpnIdToVpnInstance(dataBroker, vpnUuid.getValue());
if (vpnInstance == null || vpnInstance.getVpnId() == null) {
LOG.error("removeNATFlowEntries: No VPN associated with Ext nw {}. Unable to create SNAT table entry " + "for fixed ip {}", extNwId, mapping.getInternalIp());
return;
}
Uint32 vpnId = vpnInstance.getVpnId();
String vrfId = vpnInstance.getVrfId();
removeSNATTblEntry(dpnId, internalIp, externalIp, routerId, vpnId, removeFlowInvTx);
// Remove the DNAT default FIB flow L3_FIB_TABLE (21) -> PSNAT_TABLE (26) if SNAT is disabled
boolean isSnatEnabled = NatUtil.isSnatEnabledForRouterId(dataBroker, routerName);
if (!isSnatEnabled) {
addOrDelDefaultFibRouteForDnat(dpnId, routerName, routerId, removeFlowInvTx, false);
}
ProviderTypes provType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker, routerName, extNwId);
if (provType == null) {
LOG.error("removeNATFlowEntries : External Network Provider Type missing");
return;
}
if (provType == ProviderTypes.VXLAN) {
floatingIPHandler.onRemoveFloatingIp(dpnId, routerName, routerId, extNwId, mapping, NatConstants.DEFAULT_L3VNI_VALUE, vrfId, removeFlowInvTx);
removeOperationalDS(routerName, interfaceName, internalIp);
return;
}
Uint32 label = getOperationalIpMapping(routerName, interfaceName, internalIp);
if (label.longValue() < 0) {
LOG.error("removeNATFlowEntries : Could not retrieve label for prefix {} in router {}", internalIp, routerId);
return;
}
floatingIPHandler.onRemoveFloatingIp(dpnId, routerName, routerId, extNwId, mapping, label, vrfId, removeFlowInvTx);
removeOperationalDS(routerName, interfaceName, internalIp);
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance in project netvirt by opendaylight.
the class VpnFloatingIpHandler method onAddFloatingIp.
@Override
public void onAddFloatingIp(final Uint64 dpnId, final String routerUuid, final Uint32 routerId, final Uuid networkId, final String interfaceName, final InternalToExternalPortMap mapping, final String rd, TypedReadWriteTransaction<Configuration> confTx) {
String externalIp = mapping.getExternalIp();
String internalIp = mapping.getInternalIp();
Uuid floatingIpId = mapping.getExternalId();
Uuid subnetId = NatUtil.getFloatingIpPortSubnetIdFromFloatingIpId(dataBroker, floatingIpId);
String floatingIpPortMacAddress = NatUtil.getFloatingIpPortMacFromFloatingIpId(dataBroker, floatingIpId);
if (floatingIpPortMacAddress == null) {
LOG.error("onAddFloatingIp: Unable to retrieve floatingIp port MAC address from floatingIpId {} for " + "router {} to handle floatingIp {}", floatingIpId, routerUuid, externalIp);
return;
}
Optional<Subnets> externalSubnet = NatUtil.getOptionalExternalSubnets(dataBroker, subnetId);
final String vpnName = externalSubnet.isPresent() ? subnetId.getValue() : NatUtil.getAssociatedVPN(dataBroker, networkId);
final String subnetVpnName = externalSubnet.isPresent() ? subnetId.getValue() : null;
if (vpnName == null) {
LOG.error("onAddFloatingIp: No VPN is associated with ext nw {} to handle add floating ip {} configuration " + "for router {}", networkId, externalIp, routerId);
return;
}
if (rd == null) {
LOG.error("onAddFloatingIp: Unable to retrieve external (internet) VPN RD from external VPN {} for " + "router {} to handle floatingIp {}", vpnName, routerId, externalIp);
return;
}
ProviderTypes provType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker, routerUuid, networkId);
if (provType == null) {
return;
}
/*
* For external network of type GRE, it is required to use "Internet VPN VNI" for intra-DC
* communication, but we still require "MPLS labels" to reach SNAT/DNAT VMs from external
* entities via MPLSOverGRE.
*
* MPLSOverGRE based external networks, the ``opendaylight-vni-ranges`` pool will be
* used to carve out a unique VNI per Internet VPN (GRE-provider-type) to be used in the
* datapath for traffic forwarding for ``SNAT-to-DNAT`` and ``DNAT-to-DNAT`` cases within the
* DataCenter.
*/
String nextHopIp = NatUtil.getEndpointIpAddressForDPN(dataBroker, dpnId);
LOG.debug("onAddFloatingIp: Nexthop ip for prefix {} is {}", externalIp, nextHopIp);
if (provType == ProviderTypes.VXLAN) {
Uuid floatingIpInterface = NatEvpnUtil.getFloatingIpInterfaceIdFromFloatingIpId(dataBroker, floatingIpId);
evpnDnatFlowProgrammer.onAddFloatingIp(dpnId, routerUuid, routerId, vpnName, internalIp, externalIp, networkId, interfaceName, floatingIpInterface.getValue(), floatingIpPortMacAddress, rd, nextHopIp, confTx);
return;
}
/*
* MPLS label will be used to advertise prefixes and in "L3_LFIB_TABLE" (table 20) taking the packet
* to "INBOUND_NAPT_TABLE" (table 44) and "PDNAT_TABLE" (table 25).
*/
GenerateVpnLabelInput labelInput = new GenerateVpnLabelInputBuilder().setVpnName(vpnName).setIpPrefix(externalIp).build();
ListenableFuture<RpcResult<GenerateVpnLabelOutput>> labelFuture = vpnService.generateVpnLabel(labelInput);
ListenableFuture<RpcResult<CreateFibEntryOutput>> future = Futures.transformAsync(labelFuture, result -> {
if (result.isSuccessful()) {
GenerateVpnLabelOutput output = result.getResult();
Uint32 label = output.getLabel();
LOG.debug("onAddFloatingIp : Generated label {} for prefix {}", label, externalIp);
FloatingIPListener.updateOperationalDS(dataBroker, routerUuid, interfaceName, label, internalIp, externalIp);
/*
* For external network of type VXLAN all packets going from VMs within the DC, towards the
* external gateway device via the External VXLAN Tunnel,we are setting the VXLAN Tunnel ID to
* the L3VNI value of VPNInstance to which the VM belongs to.
*/
Uint32 l3vni = Uint32.ZERO;
if (NatUtil.isOpenStackVniSemanticsEnforcedForGreAndVxlan(elanService, provType)) {
l3vni = natOverVxlanUtil.getInternetVpnVni(vpnName, l3vni);
}
String fibExternalIp = NatUtil.validateAndAddNetworkMask(externalIp);
// Inform BGP
NatUtil.addPrefixToBGP(dataBroker, bgpManager, fibManager, vpnName, rd, fibExternalIp, nextHopIp, networkId.getValue(), floatingIpPortMacAddress, label, l3vni, RouteOrigin.STATIC, dpnId);
List<Instruction> instructions = new ArrayList<>();
List<ActionInfo> actionsInfos = new ArrayList<>();
actionsInfos.add(new ActionNxResubmit(NwConstants.PDNAT_TABLE));
instructions.add(new InstructionApplyActions(actionsInfos).buildInstruction(0));
List<ActionInfo> actionInfoFib = new ArrayList<>();
List<Instruction> customInstructions = new ArrayList<>();
actionInfoFib.add(new ActionSetFieldEthernetDestination(new MacAddress(floatingIpPortMacAddress)));
customInstructions.add(new InstructionApplyActions(actionInfoFib).buildInstruction(0));
customInstructions.add(new InstructionGotoTable(NwConstants.PDNAT_TABLE).buildInstruction(1));
LoggingFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, innerConfTx -> {
makeTunnelTableEntry(vpnName, dpnId, label, instructions, innerConfTx, provType);
makeLFibTableEntry(dpnId, label, floatingIpPortMacAddress, NwConstants.PDNAT_TABLE, innerConfTx);
}), LOG, "Error adding tunnel or FIB table entries");
CreateFibEntryInput input = new CreateFibEntryInputBuilder().setVpnName(vpnName).setSourceDpid(dpnId).setInstruction(customInstructions).setIpAddress(fibExternalIp).setServiceId(label).setIpAddressSource(CreateFibEntryInput.IpAddressSource.FloatingIP).setInstruction(customInstructions).build();
// Future<RpcResult<java.lang.Void>> createFibEntry(CreateFibEntryInput input);
ListenableFuture<RpcResult<CreateFibEntryOutput>> future1 = fibService.createFibEntry(input);
LOG.debug("onAddFloatingIp : Add Floating Ip {} , found associated to fixed port {}", externalIp, interfaceName);
String networkVpnName = NatUtil.getAssociatedVPN(dataBroker, networkId);
txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
vpnManager.addSubnetMacIntoVpnInstance(networkVpnName, subnetVpnName, floatingIpPortMacAddress, dpnId, tx);
vpnManager.addArpResponderFlowsToExternalNetworkIps(routerUuid, Collections.singleton(externalIp), floatingIpPortMacAddress, dpnId, networkId);
});
return future1;
} else {
String errMsg = String.format("onAddFloatingIp : Could not retrieve the label for prefix %s " + "in VPN %s, %s", externalIp, vpnName, result.getErrors());
LOG.error(errMsg);
return Futures.immediateFailedFuture(new RuntimeException(errMsg));
}
}, MoreExecutors.directExecutor());
Futures.addCallback(future, new FutureCallback<RpcResult<CreateFibEntryOutput>>() {
@Override
public void onFailure(@NonNull Throwable error) {
LOG.error("onAddFloatingIp : Error in generate label or fib install process", error);
}
@Override
public void onSuccess(@NonNull RpcResult<CreateFibEntryOutput> result) {
if (result.isSuccessful()) {
LOG.info("onAddFloatingIp : Successfully installed custom FIB routes for prefix {}", externalIp);
} else {
LOG.error("onAddFloatingIp : Error in rpc call to create custom Fib entries for prefix {} " + "in DPN {}, {}", externalIp, dpnId, result.getErrors());
}
}
}, MoreExecutors.directExecutor());
// Handle GARP transmission
final IpAddress extrenalAddress = IpAddressBuilder.getDefaultInstance(externalIp);
sendGarpOnInterface(dpnId, networkId, extrenalAddress, floatingIpPortMacAddress);
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance in project netvirt by opendaylight.
the class EvpnUtils method advertisePrefix.
@SuppressWarnings("checkstyle:IllegalCatch")
public void advertisePrefix(ElanInstance elanInfo, String rd, String macAddress, String prefix, String interfaceName, Uint64 dpnId) {
if (rd == null) {
LOG.debug("advertisePrefix : rd is NULL for elanInfo {}, macAddress {}", elanInfo, macAddress);
return;
}
String nextHop = getEndpointIpAddressForDPN(dpnId);
if (nextHop == null) {
LOG.debug("Failed to get the dpn tep ip for dpn {}", dpnId);
return;
}
Uint32 vpnLabel = Uint32.ZERO;
Uint32 l2vni = ElanUtils.getVxlanSegmentationId(elanInfo);
Uint32 l3vni = Uint32.ZERO;
String gatewayMacAddr = null;
String l3VpName = getL3vpnNameFromElan(elanInfo);
if (l3VpName != null) {
VpnInstance l3VpnInstance = vpnManager.getVpnInstance(broker, l3VpName);
l3vni = l3VpnInstance.getL3vni();
Optional<String> gatewayMac = getGatewayMacAddressForInterface(l3VpName, interfaceName, prefix);
gatewayMacAddr = gatewayMac.isPresent() ? gatewayMac.get() : null;
}
LOG.info("Advertising routes with rd {}, macAddress {}, prefix {}, nextHop {}," + " vpnLabel {}, l3vni {}, l2vni {}, gatewayMac {}", rd, macAddress, prefix, nextHop, vpnLabel, l3vni, l2vni, gatewayMacAddr);
try {
bgpManager.advertisePrefix(rd, macAddress, prefix, nextHop, VrfEntryBase.EncapType.Vxlan, vpnLabel, l3vni, l2vni, gatewayMacAddr);
} catch (Exception e) {
LOG.error("Failed to advertisePrefix", e);
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance in project netvirt by opendaylight.
the class NeutronvpnUtils method updateVpnInstanceWithBgpVpnType.
public void updateVpnInstanceWithBgpVpnType(VpnInstance.BgpvpnType bgpvpnType, @NonNull Uuid vpnName) {
jobCoordinator.enqueueJob("VPN-" + vpnName.getValue(), () -> {
VpnInstance vpnInstance = getVpnInstance(vpnName);
if (vpnInstance == null) {
LOG.error("updateVpnInstanceWithBgpVpnType: Failed to Update VpnInstance {} with BGP-VPN type {}." + "VpnInstance is does not exist in the CONFIG. Do nothing.", vpnName.getValue(), bgpvpnType);
return Collections.emptyList();
}
if (vpnInstance.isL2vpn()) {
LOG.error("updateVpnInstanceWithBgpVpnType: Failed to Update VpnInstance {} with BGP-VPN type {}." + "VpnInstance is L2 instance. Do nothing.", vpnName.getValue(), bgpvpnType);
return Collections.emptyList();
}
VpnInstanceBuilder builder = new VpnInstanceBuilder(vpnInstance);
builder.setBgpvpnType(bgpvpnType);
InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class).child(VpnInstance.class, new VpnInstanceKey(vpnName.getValue())).build();
LOG.info("updateVpnInstanceWithBgpVpnType: Successfully updated the VpnInstance {} with BGP-VPN type {}", vpnName.getValue(), bgpvpnType);
return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> tx.merge(vpnIdentifier, builder.build())));
});
}
Aggregations