use of org.opendaylight.mdsal.binding.api.DataBroker 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.mdsal.binding.api.DataBroker in project netvirt by opendaylight.
the class VpnFloatingIpHandler method onRemoveFloatingIp.
@Override
public void onRemoveFloatingIp(final Uint64 dpnId, String routerUuid, Uint32 routerId, final Uuid networkId, InternalToExternalPortMap mapping, final Uint32 label, final String vrfId, TypedReadWriteTransaction<Configuration> confTx) {
String externalIp = mapping.getExternalIp();
Uuid floatingIpId = mapping.getExternalId();
Uuid subnetId = NatUtil.getFloatingIpPortSubnetIdFromFloatingIpId(confTx, floatingIpId);
Optional<Subnets> externalSubnet = NatUtil.getOptionalExternalSubnets(confTx, subnetId);
final String vpnName = externalSubnet.isPresent() ? subnetId.getValue() : NatUtil.getAssociatedVPN(dataBroker, networkId);
if (vpnName == null) {
LOG.error("onRemoveFloatingIp: No VPN associated with ext nw {} to remove floating ip {} configuration " + "for router {}", networkId, externalIp, routerUuid);
return;
}
// Remove floating mac from mymac table
LOG.debug("onRemoveFloatingIp: Removing FloatingIp {}", externalIp);
String floatingIpPortMacAddress = NatUtil.getFloatingIpPortMacFromFloatingIpId(confTx, floatingIpId);
if (floatingIpPortMacAddress == null) {
LOG.error("onRemoveFloatingIp: Unable to retrieve floatingIp port MAC address from floatingIpId {} for " + "router {} to remove floatingIp {}", floatingIpId, routerUuid, externalIp);
return;
}
LoggingFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
String networkVpnName = NatUtil.getAssociatedVPN(tx, networkId);
vpnManager.removeSubnetMacFromVpnInstance(networkVpnName, subnetId.getValue(), floatingIpPortMacAddress, dpnId, tx);
vpnManager.removeArpResponderFlowsToExternalNetworkIps(routerUuid, Collections.singletonList(externalIp), floatingIpPortMacAddress, dpnId, networkId);
}), LOG, "onRemoveFloatingIp");
removeFromFloatingIpPortInfo(floatingIpId);
ProviderTypes provType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker, routerUuid, networkId);
if (provType == null) {
return;
}
if (provType == ProviderTypes.VXLAN) {
Uuid floatingIpInterface = NatEvpnUtil.getFloatingIpInterfaceIdFromFloatingIpId(dataBroker, floatingIpId);
evpnDnatFlowProgrammer.onRemoveFloatingIp(dpnId, vpnName, externalIp, floatingIpInterface.getValue(), floatingIpPortMacAddress, routerId);
return;
}
cleanupFibEntries(dpnId, vpnName, externalIp, label, vrfId, confTx, provType);
}
use of org.opendaylight.mdsal.binding.api.DataBroker in project netvirt by opendaylight.
the class RouterDpnChangeListener method add.
@Override
public void add(final InstanceIdentifier<DpnVpninterfacesList> identifier, final DpnVpninterfacesList dpnInfo) {
LOG.trace("add : key: {}, value: {}", dpnInfo.key(), dpnInfo);
final String routerUuid = identifier.firstKeyOf(RouterDpnList.class).getRouterId();
Uint64 dpnId = dpnInfo.getDpnId();
// check router is associated to external network
InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerUuid);
Optional<Routers> routerData = SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
if (routerData.isPresent()) {
Routers router = routerData.get();
Uuid networkId = router.getNetworkId();
if (networkId != null) {
if (natMode == NatMode.Conntrack) {
Uint64 naptSwitch = NatUtil.getPrimaryNaptfromRouterName(dataBroker, router.getRouterName());
if (naptSwitch == null || naptSwitch.equals(Uint64.ZERO)) {
LOG.warn("add : NAPT switch is not selected.");
return;
}
// If it is for NAPT switch skip as the flows would be already programmed.
if (naptSwitch.equals(dpnId)) {
LOG.debug("Skipping the notification recived for NAPT switch {}", routerUuid);
return;
}
LoggingFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, confTx -> {
natServiceManager.notify(confTx, router, null, naptSwitch, dpnId, SnatServiceManager.Action.CNT_ROUTER_ENBL);
if (router.isEnableSnat()) {
natServiceManager.notify(confTx, router, null, naptSwitch, naptSwitch, SnatServiceManager.Action.SNAT_ROUTER_ENBL);
}
}), LOG, "Error notifying NAT service manager");
} else {
Uint32 routerId = NatUtil.getVpnId(dataBroker, routerUuid);
if (routerId == NatConstants.INVALID_ID) {
LOG.error("add : Invalid routerId returned for routerName {}", routerUuid);
return;
}
ProviderTypes extNwProvType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker, routerUuid, networkId);
if (extNwProvType == ProviderTypes.FLAT || extNwProvType == ProviderTypes.VLAN) {
coordinator.enqueueJob(NatConstants.NAT_DJC_PREFIX + networkId, () -> {
extNetGroupInstaller.installExtNetGroupEntries(networkId, dpnId);
installDefaultNatRouteForRouterExternalSubnets(dpnId, NatUtil.getExternalSubnetIdsFromExternalIps(new ArrayList<ExternalIps>(router.nonnullExternalIps().values())));
return Collections.emptyList();
});
}
coordinator.enqueueJob(NatConstants.NAT_DJC_PREFIX + router.getRouterName(), () -> {
LOG.debug("add : Router {} is associated with ext nw {}", routerUuid, networkId);
Uuid vpnName = NatUtil.getVpnForRouter(dataBroker, routerUuid);
return Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, confTx -> {
Uint32 vpnId;
if (vpnName == null) {
LOG.debug("add : Internal vpn associated to router {}", routerUuid);
vpnId = routerId;
if (vpnId == NatConstants.INVALID_ID) {
LOG.error("add : Invalid vpnId returned for routerName {}", routerUuid);
return;
}
LOG.debug("add : Retrieved vpnId {} for router {}", vpnId, routerUuid);
// Install default entry in FIB to SNAT table
LOG.info("add : Installing default route in FIB on dpn {} for router {} with vpn {}", dpnId, routerUuid, vpnId);
snatDefaultRouteProgrammer.installDefNATRouteInDPN(dpnId, vpnId, confTx);
} else {
LOG.debug("add : External BGP vpn associated to router {}", routerUuid);
vpnId = NatUtil.getVpnId(dataBroker, vpnName.getValue());
if (vpnId == NatConstants.INVALID_ID) {
LOG.error("add : Invalid vpnId returned for routerName {}", routerUuid);
return;
}
LOG.debug("add : Retrieved vpnId {} for router {}", vpnId, routerUuid);
// Install default entry in FIB to SNAT table
LOG.debug("add : Installing default route in FIB on dpn {} for routerId {} with " + "vpnId {}...", dpnId, routerUuid, vpnId);
snatDefaultRouteProgrammer.installDefNATRouteInDPN(dpnId, vpnId, routerId, confTx);
}
/* install V6 internet default fallback rule in FIB_TABLE if router
* is having V6 subnet
*/
Uuid internetVpnId = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
if (internetVpnId != null) {
nvpnManager.programV6InternetFallbackFlow(new Uuid(routerUuid), internetVpnId, NwConstants.ADD_FLOW);
}
if (router.isEnableSnat()) {
LOG.info("add : SNAT enabled for router {}", routerUuid);
if (extNwProvType == null) {
LOG.error("add : External Network Provider Type missing");
return;
}
NatUtil.handleSNATForDPN(dataBroker, mdsalManager, idManager, naptSwitchHA, dpnId, router, routerId, vpnId, confTx, extNwProvType, upgradeState);
} else {
LOG.info("add : SNAT is not enabled for router {} to handle addDPN event {}", routerUuid, dpnId);
}
}));
}, NatConstants.NAT_DJC_MAX_RETRIES);
}
// end of controller based SNAT
}
} else {
LOG.debug("add : Router {} is not associated with External network", routerUuid);
}
}
use of org.opendaylight.mdsal.binding.api.DataBroker in project netvirt by opendaylight.
the class NatRouterInterfaceListener method add.
@Override
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
public void add(InstanceIdentifier<Interfaces> identifier, Interfaces interfaceInfo) {
LOG.trace("add : Add event - key: {}, value: {}", interfaceInfo.key(), interfaceInfo);
final String routerId = identifier.firstKeyOf(RouterInterfaces.class).getRouterId().getValue();
final String interfaceName = interfaceInfo.getInterfaceId();
if (NatUtil.isRouterInterfacePort(dataBroker, interfaceName)) {
LOG.info("ADD: Ignoring Router Interface Port {} for processing of router {}", interfaceName, routerId);
return;
}
try {
MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName), getRouterInterface(interfaceName, routerId));
} catch (Exception e) {
LOG.error("add: Unable to write data in RouterInterface model", e);
}
org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface interfaceState = NatUtil.getInterfaceStateFromOperDS(dataBroker, interfaceName);
if (interfaceState != null) {
Uint64 dpId = NatUtil.getDpIdFromInterface(interfaceState);
if (dpId.equals(Uint64.ZERO)) {
LOG.warn("ADD : Could not retrieve dp id for interface {} to handle router {} association model", interfaceName, routerId);
return;
}
final ReentrantLock lock = NatUtil.lockForNat(dpId);
lock.lock();
try {
LoggingFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operTx -> {
NatUtil.addToNeutronRouterDpnsMap(routerId, interfaceName, dpId, operTx);
NatUtil.addToDpnRoutersMap(routerId, interfaceName, dpId, operTx);
}), LOG, "Error processing NAT router interface addition");
} finally {
lock.unlock();
}
LOG.info("ADD: Added neutron-router-dpns mapping for interface {} of router {}", interfaceName, routerId);
} else {
LOG.info("add : Interface {} not yet operational to handle router interface add event in router {}", interfaceName, routerId);
}
}
use of org.opendaylight.mdsal.binding.api.DataBroker in project netvirt by opendaylight.
the class NatVpnMapsChangeListener method onRouterAssociatedToVpn.
public void onRouterAssociatedToVpn(String vpnName, String routerName) {
// check router is associated to external network
String extNetwork = NatUtil.getAssociatedExternalNetwork(dataBroker, routerName);
if (extNetwork != null) {
try {
LOG.debug("onRouterAssociatedToVpn : Router {} is associated with ext nw {}", routerName, extNetwork);
handleDNATConfigurationForRouterAssociation(routerName, vpnName, extNetwork);
Uuid extNetworkUuid = NatUtil.getNetworkIdFromRouterName(dataBroker, routerName);
if (extNetworkUuid == null) {
LOG.error("onRouterAssociatedToVpn : Unable to retrieve external network Uuid for router {}", routerName);
return;
}
ProviderTypes extNwProvType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker, routerName, extNetworkUuid);
if (extNwProvType == null) {
LOG.error("onRouterAssociatedToVpn : External Network Provider Type missing");
return;
}
Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> externalRoutersListener.changeLocalVpnIdToBgpVpnId(routerName, routerId, extNetwork, vpnName, tx, extNwProvType)).get();
} catch (InterruptedException | ExecutionException e) {
LOG.error("Error changling local VPN identifier to BGP VPN identifier", e);
}
} else {
LOG.debug("onRouterAssociatedToVpn : Ignoring the Router {} association with VPN {} " + "since it is not external router", routerName, vpnName);
}
}
Aggregations