use of org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable in project netvirt by opendaylight.
the class NaptEventHandler method buildAndGetSetActionInstructionInfo.
private static List<InstructionInfo> buildAndGetSetActionInstructionInfo(String ipAddress, int port, long segmentId, long vpnId, short tableId, NAPTEntryEvent.Protocol protocol, String extGwMacAddress) {
ActionInfo ipActionInfo = null;
ActionInfo macActionInfo = null;
ActionInfo portActionInfo = null;
ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
ArrayList<InstructionInfo> instructionInfo = new ArrayList<>();
switch(tableId) {
case NwConstants.OUTBOUND_NAPT_TABLE:
ipActionInfo = new ActionSetSourceIp(ipAddress);
// Added External Gateway MAC Address
macActionInfo = new ActionSetFieldEthernetSource(new MacAddress(extGwMacAddress));
if (protocol == NAPTEntryEvent.Protocol.TCP) {
portActionInfo = new ActionSetTcpSourcePort(port);
} else if (protocol == NAPTEntryEvent.Protocol.UDP) {
portActionInfo = new ActionSetUdpSourcePort(port);
}
// reset the split-horizon bit to allow traffic from tunnel to be sent back to the provider port
instructionInfo.add(new InstructionWriteMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID.or(MetaDataUtil.METADATA_MASK_SH_FLAG)));
break;
case NwConstants.INBOUND_NAPT_TABLE:
ipActionInfo = new ActionSetDestinationIp(ipAddress);
if (protocol == NAPTEntryEvent.Protocol.TCP) {
portActionInfo = new ActionSetTcpDestinationPort(port);
} else if (protocol == NAPTEntryEvent.Protocol.UDP) {
portActionInfo = new ActionSetUdpDestinationPort(port);
}
instructionInfo.add(new InstructionWriteMetadata(MetaDataUtil.getVpnIdMetadata(segmentId), MetaDataUtil.METADATA_MASK_VRFID));
break;
default:
LOG.error("buildAndGetSetActionInstructionInfo : Neither OUTBOUND_NAPT_TABLE nor " + "INBOUND_NAPT_TABLE matches with input table id {}", tableId);
return null;
}
listActionInfo.add(ipActionInfo);
listActionInfo.add(portActionInfo);
if (macActionInfo != null) {
listActionInfo.add(macActionInfo);
LOG.debug("buildAndGetSetActionInstructionInfo : External GW MAC Address {} is found ", macActionInfo);
}
instructionInfo.add(new InstructionApplyActions(listActionInfo));
instructionInfo.add(new InstructionGotoTable(NwConstants.NAPT_PFIB_TABLE));
return instructionInfo;
}
use of org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable in project netvirt by opendaylight.
the class EvpnSnatFlowProgrammer method evpnAdvToBgpAndInstallFibAndTsFlows.
public void evpnAdvToBgpAndInstallFibAndTsFlows(final BigInteger dpnId, final short tableId, final String externalIp, final String vpnName, final String rd, final String nextHopIp, final WriteTransaction writeTx, final long routerId, final String routerName, WriteTransaction writeFlowInvTx) {
/*
* 1) Install the flow INTERNAL_TUNNEL_TABLE (table=36)-> INBOUND_NAPT_TABLE (table=44)
* (FIP VM on DPN1 is responding back to external fixed IP on DPN2) {DNAT to SNAT traffic on
* different Hypervisor}
*
* 2) Install the flow L3_GW_MAC_TABLE (table=19)-> INBOUND_NAPT_TABLE (table=44)
* (FIP VM on DPN1 is responding back to external fixed IP on beyond DC-GW VM){DNAT to SNAT Inter DC traffic}
*
* 3) Install the flow PDNAT_TABLE (table=25)-> INBOUND_NAPT_TABLE (table=44)
* (If there is no FIP Match on table 25 (PDNAT_TABLE) then default flow to INBOUND_NAPT_TABLE (table=44))
*
* 4) Install the flow L3_FIB_TABLE (table=21)-> INBOUND_NAPT_TABLE (table=44)
* (FIP VM on DPN1 is responding back to external fixed Ip on DPN1 itself. ie. same Hypervisor)
* {DNAT to SNAT Intra DC traffic}
*/
LOG.info("evpnAdvToBgpAndInstallFibAndTsFlows : Handling SNAT Reverse Traffic for External Fixed IP {} for " + "RouterId {}", externalIp, routerId);
// Get the External Gateway MAC Address which is Router gateway MAC address for SNAT
String gwMacAddress = NatUtil.getExtGwMacAddFromRouterName(dataBroker, routerName);
if (gwMacAddress == null) {
LOG.error("evpnAdvToBgpAndInstallFibAndTsFlows : Unable to Retrieve External Gateway MAC address " + "from Router ID {}", routerId);
return;
}
// get l3Vni value for external VPN
long l3Vni = NatEvpnUtil.getL3Vni(dataBroker, rd);
if (l3Vni == NatConstants.DEFAULT_L3VNI_VALUE) {
LOG.debug("evpnAdvToBgpAndInstallFibAndTsFlows : L3VNI value is not configured in Internet VPN {}" + " and RD {} Carve-out L3VNI value from OpenDaylight VXLAN VNI Pool and continue with " + "installing SNAT flows for External Fixed IP {}", vpnName, rd, externalIp);
l3Vni = NatOverVxlanUtil.getInternetVpnVni(idManager, vpnName, routerId).longValue();
}
long vpnId = NatUtil.getVpnId(dataBroker, vpnName);
if (vpnId == NatConstants.INVALID_ID) {
LOG.error("evpnAdvToBgpAndInstallFibAndTsFlows : Invalid Vpn Id is found for Vpn Name {}", vpnName);
return;
}
/* As of now neither SNAT nor DNAT will use mac-address while advertising to FIB and BGP instead
* use only gwMacAddress. Hence default value of macAddress is null
*/
// Inform to BGP
NatEvpnUtil.addRoutesForVxLanProvType(dataBroker, bgpManager, fibManager, vpnName, rd, externalIp, nextHopIp, l3Vni, null, /*InterfaceName*/
gwMacAddress, writeTx, RouteOrigin.STATIC, dpnId);
// Install custom FIB routes - FIB table.
List<Instruction> customInstructions = new ArrayList<>();
customInstructions.add(new InstructionGotoTable(tableId).buildInstruction(0));
final String externalFixedIp = NatUtil.validateAndAddNetworkMask(externalIp);
CreateFibEntryInput input = new CreateFibEntryInputBuilder().setVpnName(vpnName).setSourceDpid(dpnId).setIpAddress(externalFixedIp).setServiceId(l3Vni).setIpAddressSource(CreateFibEntryInput.IpAddressSource.ExternalFixedIP).setInstruction(customInstructions).build();
LOG.debug("evpnAdvToBgpAndInstallFibAndTsFlows : Installing custom FIB table {} --> table {} flow on " + "NAPT Switch {} with l3Vni {}, ExternalFixedIp {}, ExternalVpnName {} for RouterId {}", NwConstants.L3_FIB_TABLE, tableId, dpnId, l3Vni, externalIp, vpnName, routerId);
Future<RpcResult<Void>> future1 = fibService.createFibEntry(input);
ListenableFuture<RpcResult<Void>> futureVxlan = JdkFutureAdapters.listenInPoolThread(future1);
final long finalL3Vni = l3Vni;
Futures.addCallback(futureVxlan, new FutureCallback<RpcResult<Void>>() {
@Override
public void onFailure(@Nonnull Throwable error) {
LOG.error("evpnAdvToBgpAndInstallFibAndTsFlows : Error in custom fib routes install process for " + "External Fixed IP {} on DPN {} with l3Vni {}, ExternalVpnName {} for RouterId {}", externalIp, dpnId, finalL3Vni, vpnName, routerId, error);
}
@Override
public void onSuccess(@Nonnull RpcResult<Void> result) {
if (result.isSuccessful()) {
LOG.info("evpnAdvToBgpAndInstallFibAndTsFlows : Successfully installed custom FIB routes for " + "External Fixed IP {} on DPN {} with l3Vni {}, ExternalVpnName {} for RouterId {}", externalIp, dpnId, finalL3Vni, vpnName, routerId);
/* Install the flow INTERNAL_TUNNEL_TABLE (table=36)-> INBOUND_NAPT_TABLE (table=44)
* (SNAT to DNAT reverse Traffic: If traffic is Initiated from NAPT to FIP VM on different Hypervisor)
*/
makeTunnelTableEntry(dpnId, finalL3Vni, customInstructions, tableId, writeFlowInvTx);
/* Install the flow L3_GW_MAC_TABLE (table=19)-> INBOUND_NAPT_TABLE (table=44)
* (SNAT reverse traffic: If the traffic is Initiated from DC-GW to VM (SNAT Reverse traffic))
*/
NatEvpnUtil.makeL3GwMacTableEntry(dpnId, vpnId, gwMacAddress, customInstructions, mdsalManager, writeFlowInvTx);
/* Install the flow PDNAT_TABLE (table=25)-> INBOUND_NAPT_TABLE (table=44)
* If there is no FIP Match on table 25 (PDNAT_TABLE)
*/
NatUtil.makePreDnatToSnatTableEntry(mdsalManager, dpnId, tableId, writeFlowInvTx);
}
}
}, MoreExecutors.directExecutor());
}
use of org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable in project netvirt by opendaylight.
the class ExternalRoutersListener method createFibTableCustomInstructions.
private List<Instruction> createFibTableCustomInstructions(short tableId, String routerName, String externalIp) {
List<Instruction> fibTableCustomInstructions = new ArrayList<>();
Routers router = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
long externalSubnetVpnId = NatUtil.getExternalSubnetVpnIdForRouterExternalIp(dataBroker, externalIp, router);
int instructionIndex = 0;
if (externalSubnetVpnId != NatConstants.INVALID_ID) {
BigInteger subnetIdMetaData = MetaDataUtil.getVpnIdMetadata(externalSubnetVpnId);
fibTableCustomInstructions.add(new InstructionWriteMetadata(subnetIdMetaData, MetaDataUtil.METADATA_MASK_VRFID).buildInstruction(instructionIndex));
instructionIndex++;
}
fibTableCustomInstructions.add(new InstructionGotoTable(tableId).buildInstruction(instructionIndex));
return fibTableCustomInstructions;
}
use of org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable in project netvirt by opendaylight.
the class AbstractSnatService method installDefaultFibRouteForSNAT.
protected void installDefaultFibRouteForSNAT(BigInteger dpnId, Long extNetId, int addOrRemove) {
List<MatchInfo> matches = new ArrayList<>();
matches.add(MatchEthernetType.IPV4);
matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNetId), MetaDataUtil.METADATA_MASK_VRFID));
List<InstructionInfo> instructions = new ArrayList<>();
instructions.add(new InstructionGotoTable(NwConstants.PSNAT_TABLE));
String flowRef = getFlowRef(dpnId, NwConstants.L3_FIB_TABLE, extNetId);
syncFlow(dpnId, NwConstants.L3_FIB_TABLE, flowRef, NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
}
use of org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable in project netvirt by opendaylight.
the class EvpnDnatFlowProgrammer method onAddFloatingIp.
public void onAddFloatingIp(final BigInteger dpnId, final String routerName, final long routerId, final String vpnName, final String internalIp, final String externalIp, final Uuid networkId, final String interfaceName, final String floatingIpInterface, final String floatingIpPortMacAddress, final String rd, final String nextHopIp, final WriteTransaction writeFlowInvTx) {
/*
* 1) Install the flow INTERNAL_TUNNEL_TABLE (table=36)-> PDNAT_TABLE (table=25) (SNAT VM on DPN1 is
* responding back to FIP VM on DPN2) {SNAT to DNAT traffic on different Hypervisor}
*
* 2) Install the flow L3_FIB_TABLE (table=21)-> PDNAT_TABLE (table=25) (FIP VM1 to FIP VM2
* Traffic on Same Hypervisor) {DNAT to DNAT on Same Hypervisor}
*
* 3) Install the flow L3_GW_MAC_TABLE (table=19)-> PDNAT_TABLE (table=25)
* (DC-GW is responding back to FIP VM) {DNAT Reverse traffic})
*
*/
long vpnId = NatUtil.getVpnId(dataBroker, vpnName);
if (vpnId == NatConstants.INVALID_ID) {
LOG.error("onAddFloatingIp : Invalid Vpn Id is found for Vpn Name {}", vpnName);
return;
}
long l3Vni = NatEvpnUtil.getL3Vni(dataBroker, rd);
if (l3Vni == NatConstants.DEFAULT_L3VNI_VALUE) {
LOG.debug("onAddFloatingIp : L3VNI value is not configured in Internet VPN {} and RD {} " + "Carve-out L3VNI value from OpenDaylight VXLAN VNI Pool and continue with installing " + "DNAT flows for FloatingIp {}", vpnName, rd, externalIp);
l3Vni = NatOverVxlanUtil.getInternetVpnVni(idManager, vpnName, routerId).longValue();
}
FloatingIPListener.updateOperationalDS(dataBroker, routerName, interfaceName, NatConstants.DEFAULT_LABEL_VALUE, internalIp, externalIp);
String fibExternalIp = NatUtil.validateAndAddNetworkMask(externalIp);
// Inform to FIB and BGP
NatEvpnUtil.addRoutesForVxLanProvType(dataBroker, bgpManager, fibManager, vpnName, rd, fibExternalIp, nextHopIp, l3Vni, floatingIpInterface, floatingIpPortMacAddress, writeFlowInvTx, RouteOrigin.STATIC, dpnId);
/* Install the flow table L3_FIB_TABLE (table=21)-> PDNAT_TABLE (table=25)
* (SNAT to DNAT reverse traffic: If the DPN has both SNAT and DNAT configured )
*/
List<ActionInfo> actionInfoFib = new ArrayList<>();
actionInfoFib.add(new ActionSetFieldEthernetDestination(new MacAddress(floatingIpPortMacAddress)));
List<Instruction> instructionsFib = new ArrayList<>();
instructionsFib.add(new InstructionApplyActions(actionInfoFib).buildInstruction(0));
instructionsFib.add(new InstructionGotoTable(NwConstants.PDNAT_TABLE).buildInstruction(1));
CreateFibEntryInput input = new CreateFibEntryInputBuilder().setVpnName(vpnName).setSourceDpid(dpnId).setIpAddress(fibExternalIp).setServiceId(l3Vni).setIpAddressSource(CreateFibEntryInput.IpAddressSource.FloatingIP).setInstruction(instructionsFib).build();
Future<RpcResult<Void>> future1 = fibService.createFibEntry(input);
ListenableFuture<RpcResult<Void>> futureVxlan = JdkFutureAdapters.listenInPoolThread(future1);
LOG.debug("onAddFloatingIp : Add Floating Ip {} , found associated to fixed port {}", externalIp, interfaceName);
if (floatingIpPortMacAddress != null) {
WriteTransaction writeTx = dataBroker.newWriteOnlyTransaction();
vpnManager.addSubnetMacIntoVpnInstance(vpnName, null, floatingIpPortMacAddress, dpnId, writeTx);
vpnManager.addArpResponderFlowsToExternalNetworkIps(routerName, Collections.singleton(externalIp), floatingIpPortMacAddress, dpnId, networkId, writeTx);
writeTx.submit();
}
final long finalL3Vni = l3Vni;
Futures.addCallback(futureVxlan, new FutureCallback<RpcResult<Void>>() {
@Override
public void onFailure(@Nonnull Throwable error) {
LOG.error("onAddFloatingIp : Error {} in custom fib routes install process for Floating " + "IP Prefix {} on DPN {}", error, externalIp, dpnId);
}
@Override
public void onSuccess(@Nonnull RpcResult<Void> result) {
if (result.isSuccessful()) {
LOG.info("onAddFloatingIp : Successfully installed custom FIB routes for Floating " + "IP Prefix {} on DPN {}", externalIp, dpnId);
List<Instruction> instructions = new ArrayList<>();
List<ActionInfo> actionsInfos = new ArrayList<>();
List<Instruction> customInstructions = new ArrayList<>();
customInstructions.add(new InstructionGotoTable(NwConstants.PDNAT_TABLE).buildInstruction(0));
actionsInfos.add(new ActionNxResubmit(NwConstants.PDNAT_TABLE));
instructions.add(new InstructionApplyActions(actionsInfos).buildInstruction(0));
/* If more than one floatingIp is available in vpn-to-dpn-list for given dpn id, do not call for
* installing INTERNAL_TUNNEL_TABLE (table=36) -> PDNAT_TABLE (table=25) flow entry with same tunnel_id
* again and again.
*/
if (!NatUtil.isFloatingIpPresentForDpn(dataBroker, dpnId, rd, vpnName, externalIp, true)) {
makeTunnelTableEntry(dpnId, finalL3Vni, instructions, writeFlowInvTx);
}
/* Install the flow L3_GW_MAC_TABLE (table=19)-> PDNAT_TABLE (table=25)
* (DNAT reverse traffic: If the traffic is Initiated from DC-GW to FIP VM (DNAT forward traffic))
*/
NatEvpnUtil.makeL3GwMacTableEntry(dpnId, vpnId, floatingIpPortMacAddress, customInstructions, mdsalManager, writeFlowInvTx);
NatUtil.waitForTransactionToComplete(writeFlowInvTx);
} else {
LOG.error("onAddFloatingIp : Error {} in rpc call to create custom Fib entries for Floating " + "IP Prefix {} on DPN {}", result.getErrors(), externalIp, dpnId);
}
}
}, MoreExecutors.directExecutor());
// Read the FIP vpn-interface details from Configuration l3vpn:vpn-interfaces model and write into Operational DS
InstanceIdentifier<VpnInterface> vpnIfIdentifier = NatUtil.getVpnInterfaceIdentifier(floatingIpInterface);
Optional<VpnInterface> optionalVpnInterface = SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
if (optionalVpnInterface.isPresent()) {
WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
for (VpnInstanceNames vpnInstance : optionalVpnInterface.get().getVpnInstanceNames()) {
if (!vpnName.equals(vpnInstance.getVpnName())) {
continue;
}
VpnInterfaceBuilder vpnIfBuilder = new VpnInterfaceBuilder(optionalVpnInterface.get());
Adjacencies adjs = vpnIfBuilder.getAugmentation(Adjacencies.class);
VpnInterfaceOpDataEntryBuilder vpnIfOpDataEntryBuilder = new VpnInterfaceOpDataEntryBuilder();
vpnIfOpDataEntryBuilder.setKey(new VpnInterfaceOpDataEntryKey(interfaceName, vpnName));
List<Adjacency> adjacencyList = adjs != null ? adjs.getAdjacency() : new ArrayList<>();
List<Adjacency> adjacencyListToImport = new ArrayList<>();
for (Adjacency adj : adjacencyList) {
Subnetmap sn = VpnHelper.getSubnetmapFromItsUuid(dataBroker, adj.getSubnetId());
if (!VpnHelper.isSubnetPartOfVpn(sn, vpnName)) {
continue;
}
adjacencyListToImport.add(adj);
}
AdjacenciesOp adjacenciesOp = new AdjacenciesOpBuilder().setAdjacency(adjacencyListToImport).build();
vpnIfOpDataEntryBuilder.addAugmentation(AdjacenciesOp.class, adjacenciesOp);
LOG.debug("onAddFloatingIp : Add vpnInterface {} to Operational l3vpn:vpn-interfaces-op-data ", floatingIpInterface);
InstanceIdentifier<VpnInterfaceOpDataEntry> vpnIfIdentifierOpDataEntry = NatUtil.getVpnInterfaceOpDataEntryIdentifier(interfaceName, vpnName);
writeOperTxn.put(LogicalDatastoreType.OPERATIONAL, vpnIfIdentifierOpDataEntry, vpnIfOpDataEntryBuilder.build(), WriteTransaction.CREATE_MISSING_PARENTS);
break;
}
ListenableFuture<Void> futures = writeOperTxn.submit();
String errorText = "onAddFloatingIp : Could not write Interface " + interfaceName + " vpnName " + vpnName;
ListenableFutures.addErrorLogging(futures, LOG, errorText);
} else {
LOG.debug("onAddFloatingIp : No vpnInterface {} found in Configuration l3vpn:vpn-interfaces ", floatingIpInterface);
}
}
Aggregations