use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes in project netvirt by opendaylight.
the class FloatingIPListener method removeNATFlowEntries.
void removeNATFlowEntries(String interfaceName, final InternalToExternalPortMap mapping, InstanceIdentifier<RouterPorts> portIid, final String routerName, BigInteger dpnId, WriteTransaction removeFlowInvTx) {
String internalIp = mapping.getInternalIp();
String externalIp = mapping.getExternalIp();
// Get the DPN on which this interface resides
if (dpnId == null) {
dpnId = NatUtil.getDpnForInterface(interfaceManager, interfaceName);
if (dpnId.equals(BigInteger.ZERO)) {
LOG.warn("removeNATFlowEntries: Abort processing Floating ip configuration. No DPN for port: {}", interfaceName);
return;
}
}
long 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;
}
// Delete the DNAT and SNAT table entries
removeDNATTblEntry(dpnId, internalIp, externalIp, routerId, removeFlowInvTx);
Uuid extNwId = getExtNetworkId(portIid, LogicalDatastoreType.OPERATIONAL);
if (extNwId == null) {
LOG.error("removeNATFlowEntries : External network associated with interface {} could not be retrieved", interfaceName);
return;
}
long vpnId = getVpnId(extNwId, mapping.getExternalId());
if (vpnId < 0) {
LOG.error("removeNATFlowEntries : No VPN associated with ext nw {}. Unable to delete SNAT table " + "entry for fixed ip {}", extNwId, internalIp);
return;
}
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, removeFlowInvTx);
removeOperationalDS(routerName, interfaceName, internalIp);
return;
}
long label = getOperationalIpMapping(routerName, interfaceName, internalIp);
if (label < 0) {
LOG.error("removeNATFlowEntries : Could not retrieve label for prefix {} in router {}", internalIp, routerId);
return;
}
floatingIPHandler.onRemoveFloatingIp(dpnId, routerName, routerId, extNwId, mapping, (int) label, removeFlowInvTx);
removeOperationalDS(routerName, interfaceName, internalIp);
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes in project netvirt by opendaylight.
the class VpnFloatingIpHandler method onAddFloatingIp.
@Override
public void onAddFloatingIp(final BigInteger dpnId, final String routerUuid, final long routerId, final Uuid networkId, final String interfaceName, final InternalToExternalPortMap mapping, WriteTransaction writeFlowInvTx) {
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;
}
String rd = NatUtil.getVpnRd(dataBroker, vpnName);
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.
*/
if (NatUtil.isOpenStackVniSemanticsEnforcedForGreAndVxlan(elanService, provType)) {
NatOverVxlanUtil.validateAndCreateVxlanVniPool(dataBroker, nvpnManager, idManager, NatConstants.ODL_VNI_POOL_NAME);
}
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, writeFlowInvTx);
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();
Future<RpcResult<GenerateVpnLabelOutput>> labelFuture = vpnService.generateVpnLabel(labelInput);
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("onAddFloatingIp : Generated label {} for prefix {}", label, externalIp);
FloatingIPListener.updateOperationalDS(dataBroker, routerUuid, interfaceName, label, internalIp, externalIp);
long l3vni = 0;
if (NatUtil.isOpenStackVniSemanticsEnforcedForGreAndVxlan(elanService, provType)) {
l3vni = NatOverVxlanUtil.getInternetVpnVni(idManager, vpnName, l3vni).longValue();
}
String fibExternalIp = NatUtil.validateAndAddNetworkMask(externalIp);
NatUtil.addPrefixToBGP(dataBroker, bgpManager, fibManager, vpnName, rd, subnetId, 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));
makeTunnelTableEntry(vpnName, dpnId, label, instructions, writeFlowInvTx, provType);
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));
makeLFibTableEntry(dpnId, label, floatingIpPortMacAddress, NwConstants.PDNAT_TABLE, writeFlowInvTx);
CreateFibEntryInput input = new CreateFibEntryInputBuilder().setVpnName(vpnName).setSourceDpid(dpnId).setInstruction(customInstructions).setIpAddress(fibExternalIp).setServiceId(label).setIpAddressSource(CreateFibEntryInput.IpAddressSource.FloatingIP).setInstruction(customInstructions).build();
Future<RpcResult<Void>> 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(tx -> {
vpnManager.addSubnetMacIntoVpnInstance(networkVpnName, subnetVpnName, floatingIpPortMacAddress, dpnId, tx);
vpnManager.addArpResponderFlowsToExternalNetworkIps(routerUuid, Collections.singleton(externalIp), floatingIpPortMacAddress, dpnId, networkId, tx);
});
return JdkFutureAdapters.listenInPoolThread(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<Void>>() {
@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<Void> 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.natservice.rev160111.ProviderTypes in project netvirt by opendaylight.
the class VpnFloatingIpHandler method makeTunnelTableEntry.
private void makeTunnelTableEntry(String vpnName, BigInteger dpnId, long serviceId, List<Instruction> customInstructions, WriteTransaction writeFlowInvTx, ProviderTypes provType) {
List<MatchInfo> mkMatches = new ArrayList<>();
LOG.info("makeTunnelTableEntry on DpnId = {} and serviceId = {}", dpnId, serviceId);
int flowPriority = 5;
// then handled back to using using flow 25->44(which will be installed as part of SNAT)
if (NatUtil.isOpenStackVniSemanticsEnforcedForGreAndVxlan(elanService, provType)) {
mkMatches.add(new MatchTunnelId(NatOverVxlanUtil.getInternetVpnVni(idManager, vpnName, serviceId)));
flowPriority = 6;
} else {
mkMatches.add(new MatchTunnelId(BigInteger.valueOf(serviceId)));
}
Flow terminatingServiceTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE, getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, serviceId, ""), flowPriority, String.format("%s:%d", "TST Flow Entry ", serviceId), 0, 0, COOKIE_TUNNEL.add(BigInteger.valueOf(serviceId)), mkMatches, customInstructions);
mdsalManager.addFlowToTx(dpnId, terminatingServiceTableFlowEntity, writeFlowInvTx);
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes in project netvirt by opendaylight.
the class VxlanGreConntrackBasedSnatService method handleSnat.
@Override
public boolean handleSnat(Routers routers, BigInteger primarySwitchId, BigInteger dpnId, int addOrRemove) {
ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
LOG.debug("VxlanGreConntrackBasedSnatService: handleSnat ProviderTypes {}", extNwProviderType);
if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
return false;
}
return super.handleSnat(routers, primarySwitchId, dpnId, addOrRemove);
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes in project netvirt by opendaylight.
the class NaptSwitchHA method bestEffortDeletion.
protected void bestEffortDeletion(long routerId, String routerName, Map<String, Long> externalIpLabel, WriteTransaction removeFlowInvTx) {
Collection<String> newExternalIps = NatUtil.getExternalIpsForRouter(dataBroker, routerId);
if (externalIpsCache != null) {
Set<String> removedExternalIps = new HashSet<>(externalIpsCache);
removedExternalIps.removeAll(newExternalIps);
if (removedExternalIps.isEmpty()) {
LOG.info("bestEffortDeletion : No external Ip needed to be removed in bestEffortDeletion " + "method for router {}", routerName);
return;
}
Uuid networkId = NatUtil.getNetworkIdFromRouterName(dataBroker, routerName);
String vpnName = getExtNetworkVpnName(routerName, networkId);
if (vpnName == null) {
LOG.error("bestEffortDeletion : Vpn is not associated to externalN/w of router {}", routerName);
return;
}
BigInteger naptSwitch = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
if (naptSwitch == null || naptSwitch.equals(BigInteger.ZERO)) {
LOG.error("bestEffortDeletion : No naptSwitch is selected for router {}", routerName);
return;
}
ProviderTypes extNwProvType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker, routerName, networkId);
if (extNwProvType == null) {
return;
}
String gwMacAddress = NatUtil.getExtGwMacAddFromRouterName(dataBroker, routerName);
if (gwMacAddress != null) {
LOG.debug("bestEffortDeletion : External Gateway MAC address {} found for External Router ID {}", gwMacAddress, routerId);
} else {
LOG.error("bestEffortDeletion : No External Gateway MAC address found for External Router ID {}", routerId);
return;
}
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, removeFlowInvTx);
LOG.debug("bestEffortDeletion : Successfully removed fib entry for externalIp {} for routerId {} " + "on NAPT switch {} ", externalIp, routerId, naptSwitch);
}
} else {
if (externalIpLabel == null || externalIpLabel.isEmpty()) {
LOG.error("bestEffortDeletion : ExternalIpLabel map is empty for router {}", routerName);
return;
}
Long label;
for (String externalIp : removedExternalIps) {
if (externalIpLabel.containsKey(externalIp)) {
label = externalIpLabel.get(externalIp);
LOG.debug("bestEffortDeletion : Label {} for ExternalIp {} for router {}", label, externalIp, routerName);
} else {
LOG.debug("bestEffortDeletion : Label for ExternalIp {} is not found for router {}", externalIp, routerName);
continue;
}
externalRouterListener.clearBgpRoutes(externalIp, vpnName);
externalRouterListener.delFibTsAndReverseTraffic(naptSwitch, routerId, externalIp, vpnName, networkId, label, gwMacAddress, true, removeFlowInvTx);
LOG.debug("bestEffortDeletion : Successfully removed fib entries in switch {} for router {} " + "and externalIps {}", naptSwitch, routerId, externalIp);
}
}
} else {
LOG.debug("bestEffortDeletion : No external IP found for router {}", routerId);
}
}
Aggregations