use of org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.Instructions in project netvirt by opendaylight.
the class VrfEntryListener method removeInterVPNLinkRouteFlows.
public void removeInterVPNLinkRouteFlows(final InterVpnLinkDataComposite interVpnLink, final String vpnName, final VrfEntry vrfEntry) {
Preconditions.checkArgument(vrfEntry.getRoutePaths() != null && vrfEntry.getRoutePaths().size() == 1);
String interVpnLinkName = interVpnLink.getInterVpnLinkName();
List<BigInteger> targetDpns = interVpnLink.getEndpointDpnsByVpnName(vpnName);
if (targetDpns.isEmpty()) {
LOG.warn("Could not find DPNs for VPN {} in InterVpnLink {}", vpnName, interVpnLinkName);
return;
}
java.util.Optional<String> optNextHop = FibUtil.getFirstNextHopAddress(vrfEntry);
java.util.Optional<Long> optLabel = FibUtil.getLabelFromRoutePaths(vrfEntry);
// delete from FIB
//
optNextHop.ifPresent(nextHop -> {
String flowRef = getInterVpnFibFlowRef(interVpnLinkName, vrfEntry.getDestPrefix(), nextHop);
FlowKey flowKey = new FlowKey(new FlowId(flowRef));
Flow flow = new FlowBuilder().setKey(flowKey).setId(new FlowId(flowRef)).setTableId(NwConstants.L3_FIB_TABLE).setFlowName(flowRef).build();
LOG.trace("Removing flow in FIB table for interVpnLink {} key {}", interVpnLinkName, flowRef);
for (BigInteger dpId : targetDpns) {
LOG.debug("Removing flow: VrfEntry=[prefix={} nexthop={}] dpn {} for InterVpnLink {} in FIB", vrfEntry.getDestPrefix(), nextHop, dpId, interVpnLinkName);
mdsalManager.removeFlow(dpId, flow);
}
});
// delete from LFIB
//
optLabel.ifPresent(label -> {
LOG.trace("Removing flow in FIB table for interVpnLink {}", interVpnLinkName);
WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
for (BigInteger dpId : targetDpns) {
LOG.debug("Removing flow: VrfEntry=[prefix={} label={}] dpn {} for InterVpnLink {} in LFIB", vrfEntry.getDestPrefix(), label, dpId, interVpnLinkName);
makeLFibTableEntry(dpId, label, /*instructions*/
null, LFIB_INTERVPN_PRIORITY, NwConstants.DEL_FLOW, tx);
}
tx.submit();
});
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.Instructions in project netvirt by opendaylight.
the class EvpnVrfEntryHandler method createRemoteFibEntry.
private void createRemoteFibEntry(final BigInteger remoteDpnId, final long vpnId, final VrfTablesKey vrfTableKey, final VrfEntry vrfEntry, boolean isNatPrefix, WriteTransaction tx) {
String rd = vrfTableKey.getRouteDistinguisher();
List<SubTransaction> subTxns = new ArrayList<>();
LOG.debug("createremotefibentry: adding route {} for rd {} with transaction {}", vrfEntry.getDestPrefix(), rd, tx);
List<NexthopManager.AdjacencyResult> tunnelInterfaceList = resolveAdjacency(remoteDpnId, vpnId, vrfEntry, rd);
if (tunnelInterfaceList.isEmpty()) {
LOG.error("Could not get interface for route-paths: {} in vpn {}", vrfEntry.getRoutePaths(), rd);
LOG.warn("Failed to add Route: {} in vpn: {}", vrfEntry.getDestPrefix(), rd);
return;
}
for (NexthopManager.AdjacencyResult adjacencyResult : tunnelInterfaceList) {
List<ActionInfo> actionInfos = new ArrayList<>();
BigInteger tunnelId;
String prefix = adjacencyResult.getPrefix();
Prefixes prefixInfo = getFibUtil().getPrefixToInterface(vpnId, prefix);
String interfaceName = prefixInfo.getVpnInterfaceName();
if (vrfEntry.getOrigin().equals(RouteOrigin.BGP.getValue()) || isNatPrefix) {
tunnelId = BigInteger.valueOf(vrfEntry.getL3vni());
} else if (elanManager.isOpenStackVniSemanticsEnforced()) {
tunnelId = BigInteger.valueOf(getFibUtil().getVniForVxlanNetwork(prefixInfo.getSubnetId()).get());
} else {
Interface interfaceState = getFibUtil().getInterfaceStateFromOperDS(interfaceName);
tunnelId = BigInteger.valueOf(interfaceState.getIfIndex());
}
LOG.debug("adding set tunnel id action for label {}", tunnelId);
String macAddress = null;
String vpnName = getFibUtil().getVpnNameFromId(vpnId);
if (vpnName == null) {
LOG.debug("Failed to get VPN name for vpnId {}", vpnId);
return;
}
if (interfaceName != null) {
macAddress = getFibUtil().getMacAddressFromPrefix(interfaceName, vpnName, prefix);
actionInfos.add(new ActionSetFieldEthernetDestination(new MacAddress(macAddress)));
}
actionInfos.add(new ActionSetFieldTunnelId(tunnelId));
List<ActionInfo> egressActions = nexthopManager.getEgressActionsForInterface(adjacencyResult.getInterfaceName(), actionInfos.size());
if (egressActions.isEmpty()) {
LOG.error("Failed to retrieve egress action for prefix {} route-paths {} interface {}." + " Aborting remote FIB entry creation..", vrfEntry.getDestPrefix(), vrfEntry.getRoutePaths(), adjacencyResult.getInterfaceName());
return;
}
actionInfos.addAll(egressActions);
List<InstructionInfo> instructions = new ArrayList<>();
instructions.add(new InstructionApplyActions(actionInfos));
makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, instructions, NwConstants.ADD_FLOW, tx, subTxns);
}
LOG.debug("Successfully added FIB entry for prefix {} in rd {}", vrfEntry.getDestPrefix(), rd);
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.Instructions in project netvirt by opendaylight.
the class ElanServiceChainUtils method programLPortDispatcherFromScf.
/**
* This flow is in charge of handling packets coming from the SCF Pipeline
* when there is no matching ServiceChain.
* <ul>
* <li> Matches on ElanPseudoPortTag and SI=3 (ELAN)</li>
* <li> Sets elanTag and sends to DMAC table</li>
* </ul>
* @param dpnId Dpn Id where the flow must be installed
* @param elanLportTag the Elan Pseudo Lport Id to be used in the Dataplane
* @param elanTag the Elan Id to be used in the Dataplane
* @param addOrRemove States if the flow must be added or removed
*/
public static void programLPortDispatcherFromScf(IMdsalApiManager mdsalManager, BigInteger dpnId, int elanLportTag, long elanTag, int addOrRemove) {
LOG.info("L2-ServiceChaining: programLPortDispatcherFromScf dpId={} elanLportTag={} elanTag={} addOrRemove={} ", dpnId, elanLportTag, elanTag, addOrRemove);
String flowRef = buildLportDispFromScfFlowRef(elanTag, elanLportTag);
if (addOrRemove == NwConstants.ADD_FLOW) {
List<MatchInfo> matches = Collections.singletonList(new MatchMetadata(MetaDataUtil.getMetaDataForLPortDispatcher(elanLportTag, ServiceIndex.getIndex(NwConstants.ELAN_SERVICE_NAME, NwConstants.ELAN_SERVICE_INDEX)), MetaDataUtil.getMetaDataMaskForLPortDispatcher()));
int instructionKey = 0;
List<Instruction> instructions = Arrays.asList(// while going through the SCF Pipeline
MDSALUtil.buildAndGetWriteMetadaInstruction(getElanMetadataLabel(elanTag).or(BigInteger.ONE), MetaDataUtil.METADATA_MASK_SERVICE.or(BigInteger.ONE), instructionKey++), MDSALUtil.buildAndGetGotoTableInstruction(NwConstants.ELAN_SMAC_TABLE, instructionKey));
Flow flow = MDSALUtil.buildFlowNew(NwConstants.LPORT_DISPATCHER_TABLE, flowRef, CloudServiceChainConstants.DEFAULT_SCF_FLOW_PRIORITY, flowRef, 0, 0, CloudServiceChainConstants.COOKIE_LPORT_DISPATCHER_BASE.add(BigInteger.valueOf(elanTag)), matches, instructions);
mdsalManager.installFlow(dpnId, flow);
} else {
Flow flow = new FlowBuilder().setTableId(NwConstants.LPORT_DISPATCHER_TABLE).setId(new FlowId(flowRef)).build();
mdsalManager.removeFlow(dpnId, flow);
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.Instructions in project netvirt by opendaylight.
the class ElanServiceChainUtils method programLPortDispatcherToScf.
/**
* This flow is in charge of handling packets coming from ExtTunnelTable
* that must be redirected to the SCF Pipeline.
* + Matches on lportTag=ElanPseudoLportTag + SI=1
* + Sets scfTag and sends to the DlSubsFilter table.
*
* @param dpnId Dpn Id where the flow must be installed
* @param elanLportTag the Elan Pseudo Lport Id in Dataplane
* @param elanTag the Elan Id in the Dataplane
* @param addOrRemove States if the flow must be added or removed
*/
public static void programLPortDispatcherToScf(IMdsalApiManager mdsalManager, BigInteger dpnId, long elanTag, int elanLportTag, short tableId, long scfTag, int addOrRemove) {
LOG.info("L2-ServiceChaining: programLPortDispatcherToScf dpId={} elanLportTag={} scfTag={} addOrRemove={} ", dpnId, elanLportTag, scfTag, addOrRemove);
String flowRef = buildLportDispToScfFlowRef(elanLportTag, scfTag);
if (addOrRemove == NwConstants.ADD_FLOW) {
int instructionKey = 0;
List<Instruction> instructions = new ArrayList<>();
List<ActionInfo> actionsInfos = new ArrayList<>();
actionsInfos.add(new ActionRegLoad(NxmNxReg2.class, 0, 31, scfTag));
instructions.add(MDSALUtil.buildApplyActionsInstruction(MDSALUtil.buildActions(actionsInfos), instructionKey++));
instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(tableId, instructionKey++));
List<MatchInfo> matches = Collections.singletonList(new MatchMetadata(MetaDataUtil.getMetaDataForLPortDispatcher(elanLportTag, ServiceIndex.getIndex(NwConstants.SCF_SERVICE_NAME, NwConstants.SCF_SERVICE_INDEX)), MetaDataUtil.getMetaDataMaskForLPortDispatcher()));
Flow flow = MDSALUtil.buildFlowNew(NwConstants.LPORT_DISPATCHER_TABLE, flowRef, CloudServiceChainConstants.DEFAULT_SCF_FLOW_PRIORITY, flowRef, 0, 0, CloudServiceChainConstants.COOKIE_LPORT_DISPATCHER_BASE.add(BigInteger.valueOf(elanTag)), matches, instructions);
mdsalManager.installFlow(dpnId, flow);
} else {
Flow flow = new FlowBuilder().setTableId(NwConstants.LPORT_DISPATCHER_TABLE).setId(new FlowId(flowRef)).build();
mdsalManager.removeFlow(dpnId, flow);
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.Instructions in project netvirt by opendaylight.
the class VpnServiceChainUtils method buildLPortDispFromScfToL3VpnFlow.
/**
* Build the flow that must be inserted when there is a ScHop whose
* egressPort is a VPN Pseudo Port. In that case, packets must be moved
* from the SCF to VPN Pipeline.
* <p>
* Flow matches: VpnPseudo port lPortTag + SI=L3VPN
* Actions: Write vrfTag in Metadata + goto FIB Table
* </p>
* @param vpnId Dataplane identifier of the VPN, the Vrf Tag.
* @param dpId The DPN where the flow must be installed/removed
* @param lportTag Dataplane identifier for the VpnPseudoPort
* @param addOrRemove States if it must build a Flow to be created or
* removed
*
* @return the Flow object
*/
public static Flow buildLPortDispFromScfToL3VpnFlow(Long vpnId, BigInteger dpId, Integer lportTag, int addOrRemove) {
LOG.info("buildLPortDispFlowForScf vpnId={} dpId={} lportTag={} addOrRemove={} ", vpnId, dpId, lportTag, addOrRemove);
List<MatchInfo> matches = buildMatchOnLportTagAndSI(lportTag, ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, NwConstants.L3VPN_SERVICE_INDEX));
List<Instruction> instructions = buildSetVrfTagAndGotoFibInstructions(vpnId.intValue());
String flowRef = getScfToL3VpnLportDispatcherFlowRef(lportTag);
Flow result;
if (addOrRemove == NwConstants.ADD_FLOW) {
result = MDSALUtil.buildFlowNew(NwConstants.LPORT_DISPATCHER_TABLE, flowRef, CloudServiceChainConstants.DEFAULT_SCF_FLOW_PRIORITY, flowRef, 0, 0, VpnServiceChainUtils.getCookieL3(vpnId.intValue()), matches, instructions);
} else {
result = new FlowBuilder().setTableId(NwConstants.LPORT_DISPATCHER_TABLE).setId(new FlowId(flowRef)).build();
}
return result;
}
Aggregations