use of org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableId in project netvirt by opendaylight.
the class ArpResponderUtil method getExtInterfaceInstructions.
/**
* Get instruction list for ARP responder flows originated from ext-net e.g.
* router-gw/fip.<br>
* The split-horizon bit should be reset in order to allow traffic from
* provider network to be routed back to flat/VLAN network and override the
* egress table drop flow.<br>
* In order to allow write-metadata in the ARP responder table the resubmit
* action needs to be replaced with goto instruction.
*/
public static List<Instruction> getExtInterfaceInstructions(IInterfaceManager ifaceMgrRpcService, String extInterfaceName, String ipAddress, String macAddress) {
AtomicInteger tableId = new AtomicInteger(-1);
List<Instruction> instructions = new ArrayList<>();
List<Action> actions = getActions(ifaceMgrRpcService, extInterfaceName, ipAddress, macAddress);
actions.removeIf(v -> {
org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionClass = v.getAction();
if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
tableId.set(((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable());
return true;
} else {
return false;
}
});
instructions.add(MDSALUtil.buildApplyActionsInstruction(actions, 0));
if (tableId.get() != -1) {
// write-metadata
if ((short) tableId.get() > NwConstants.ARP_RESPONDER_TABLE) {
instructions.add(new InstructionGotoTable((short) tableId.get()).buildInstruction(2));
} else {
LOG.warn("Failed to insall responder flow for interface {}. Resubmit to {} can't be replaced with goto", extInterfaceName, tableId);
}
}
return instructions;
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableId in project netvirt by opendaylight.
the class ElanServiceChainHandler method programElanScfPipeline.
/**
* Programs the needed flows for sending traffic to the SCF pipeline when
* it is comming from an L2-GW (ELAN) and also for handing over that
* traffic from SCF to ELAN when the packets does not match any Service
* Chain.
*
* @param elanName Name of the ELAN to be considered
* @param tableId Table id, in the SCF Pipeline, to which the traffic must
* go to.
* @param scfTag Tag of the ServiceChain
* @param elanLportTag LPortTag of the ElanPseudoPort that participates in
* the ServiceChain
* @param addOrRemove States if the flows must be created or removed
*/
public void programElanScfPipeline(String elanName, short tableId, long scfTag, int elanLportTag, int addOrRemove) {
LOG.info("programElanScfPipeline: elanName={} scfTag={} elanLportTag={} addOrRemove={}", elanName, scfTag, elanLportTag, addOrRemove);
// There are 3 rules to be considered:
// 1. LportDispatcher To Scf. Matches on elanPseudoPort + SI=1. Goes to DL Subscriber table
// 2. LportDispatcher From Scf. Matches on elanPseudoPort + SI=3. Goes to ELAN DMAC
// 3. ExtTunnelTable From L2GwDevice. Matches on VNI + SI=1. Sets ElanPseudoPort tag and goes
// to LportDispatcher table.
// And these rules must be programmed in all the Elan footprint
// Find the ElanInstance
Optional<ElanInstance> elanInstance = ElanServiceChainUtils.getElanInstanceByName(broker, elanName);
if (!elanInstance.isPresent()) {
LOG.debug("Could not find an Elan Instance with name={}", elanName);
return;
}
Collection<BigInteger> elanDpnsOpc = ElanServiceChainUtils.getElanDpnsByName(broker, elanName);
if (elanDpnsOpc.isEmpty()) {
LOG.debug("Could not find any DPN related to Elan {}", elanName);
return;
}
// updates map which stores relationship between elan and elanLPortTag and scfTag
ElanServiceChainUtils.updateElanToLportTagMap(broker, elanName, elanLportTag, scfTag, addOrRemove);
Long vni = elanInstance.get().getSegmentationId();
if (vni == null) {
LOG.warn("There is no VNI for elan {}. VNI is mandatory. Returning", elanName);
return;
}
int elanTag = elanInstance.get().getElanTag().intValue();
LOG.debug("elanName={} -> vni={} elanTag={}", elanName, vni, elanTag);
// Program ExtTunnelTable.
for (BigInteger dpnId : elanDpnsOpc) {
ElanServiceChainUtils.programLPortDispatcherToScf(mdsalManager, dpnId, elanTag, elanLportTag, tableId, scfTag, addOrRemove);
ElanServiceChainUtils.programLPortDispatcherFromScf(mdsalManager, dpnId, elanLportTag, elanTag, addOrRemove);
ElanServiceChainUtils.programExternalTunnelTable(mdsalManager, dpnId, elanLportTag, vni, elanTag, addOrRemove);
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableId in project netvirt by opendaylight.
the class VPNServiceChainHandler method programVpnToScfPipeline.
/**
* Programs the necessary flows in LFIB and LPortDispatcher table so that
* the packets coming from a given VPN are delivered to a given
* ServiceChain Pipeline.
*
* @param vpnName Name of the VPN. Typically the UUID
* @param tableId Table to which the LPortDispatcher table sends the packet
* to (Uplink or Downlink Subsc table)
* @param scfTag Scf tag to the SCF to which the Vpn is linked to.
* @param lportTag VpnPseudo Port lportTag
* @param addOrRemove States if the VPN2SCF Pipeline must be installed or
* removed
*/
public void programVpnToScfPipeline(String vpnName, short tableId, long scfTag, int lportTag, int addOrRemove) {
// This entries must be created in the DPN where the CGNAT is installed. Since it is not possible
// to know where CGNAT is located, this entries are installed in all the VPN footprint.
// LFIB:
// - Match: cgnatLabel Instr: lportTag=vpnPseudoPortTag + SI=SCF + GOTO 17
// LportDisp:
// - Match: vpnPseudoPortTag + SI==SCF Instr: scfTag + GOTO 70
LOG.info("programVpnToScfPipeline ({}) : Parameters VpnName:{} tableId:{} scftag:{} lportTag:{}", addOrRemove == NwConstants.ADD_FLOW ? "Creation" : "Removal", vpnName, tableId, scfTag, lportTag);
String rd = VpnServiceChainUtils.getVpnRd(dataBroker, vpnName);
LOG.debug("Router distinguisher (rd):{}", rd);
if (rd == null || rd.isEmpty()) {
LOG.warn("programVpnToScfPipeline: Could not find Router-distinguisher for VPN {}. No further actions", vpnName);
return;
}
VpnInstanceOpDataEntry vpnInstance = getVpnInstance(rd);
if (vpnInstance == null) {
LOG.warn("Could not find a suitable VpnInstance for Route-Distinguisher={}", rd);
return;
}
// Find out the set of DPNs for the given VPN ID
Collection<VpnToDpnList> vpnToDpnList = vpnInstance.getVpnToDpnList();
List<VrfEntry> vrfEntries = VpnServiceChainUtils.getAllVrfEntries(dataBroker, rd);
if (vrfEntries != null) {
if (addOrRemove == NwConstants.ADD_FLOW) {
AddVpnPseudoPortDataJob updateVpnToPseudoPortTask = new AddVpnPseudoPortDataJob(dataBroker, rd, lportTag, tableId, (int) scfTag);
jobCoordinator.enqueueJob(updateVpnToPseudoPortTask.getDsJobCoordinatorKey(), updateVpnToPseudoPortTask);
} else {
RemoveVpnPseudoPortDataJob removeVpnPseudoPortDataTask = new RemoveVpnPseudoPortDataJob(dataBroker, rd);
jobCoordinator.enqueueJob(removeVpnPseudoPortDataTask.getDsJobCoordinatorKey(), removeVpnPseudoPortDataTask);
}
for (VpnToDpnList dpnInVpn : vpnToDpnList) {
BigInteger dpnId = dpnInVpn.getDpnId();
programVpnToScfPipelineOnDpn(dpnId, vrfEntries, tableId, (int) scfTag, lportTag, addOrRemove);
if (dpnInVpn.getVpnInterfaces() != null) {
long vpnId = vpnInstance.getVpnId();
Flow flow = VpnServiceChainUtils.buildLPortDispFromScfToL3VpnFlow(vpnId, dpnId, lportTag, NwConstants.ADD_FLOW);
if (addOrRemove == NwConstants.ADD_FLOW) {
mdsalManager.installFlow(dpnId, flow);
} else {
mdsalManager.removeFlow(dpnId, flow);
}
dpnInVpn.getVpnInterfaces().forEach(vpnIf -> {
if (addOrRemove == NwConstants.ADD_FLOW) {
bindScfOnVpnInterface(vpnIf.getInterfaceName(), (int) scfTag);
} else {
unbindScfOnVpnInterface(vpnIf.getInterfaceName());
}
});
}
}
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableId in project netvirt by opendaylight.
the class ElanDpnInterfacesListener method add.
@Override
protected void add(InstanceIdentifier<DpnInterfaces> identifier, final DpnInterfaces dpnInterfaces) {
final String elanName = getElanName(identifier);
BigInteger addDpnId = dpnInterfaces.getDpId();
LOG.debug("ELAN interfaces {} added on DPN {} for Elan {}", dpnInterfaces.getInterfaces(), addDpnId, elanName);
Optional<ElanServiceChainState> elanServiceChainState = ElanServiceChainUtils.getElanServiceChainState(broker, elanName);
if (elanServiceChainState.isPresent()) {
List<ElanToPseudoPortData> elanToPseudoPortDataList = elanServiceChainState.get().getElanToPseudoPortData();
for (ElanToPseudoPortData elanToPseudoPortData : elanToPseudoPortDataList) {
Long scfTag = elanToPseudoPortData.getScfTag();
Long elanLportTag = elanToPseudoPortData.getElanLportTag();
if (elanLportTag != null && scfTag != null) {
short tableId = NwConstants.SCF_DOWN_SUB_FILTER_TCP_BASED_TABLE;
handleUpdate(addDpnId, elanName, tableId, elanLportTag.intValue(), /*21 bit*/
scfTag, NwConstants.ADD_FLOW);
} else {
LOG.debug("Could not find lportTag for ELAN={}", elanName);
}
}
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableId in project openflowplugin by opendaylight.
the class LearningSwitchHandlerSimpleImpl method addBridgeFlow.
private void addBridgeFlow(MacAddress srcMac, MacAddress dstMac, NodeConnectorRef destNodeConnector) {
synchronized (coveredMacPaths) {
String macPath = srcMac.toString() + dstMac.toString();
if (!coveredMacPaths.contains(macPath)) {
LOG.debug("covering mac path: {} by [{}]", macPath, destNodeConnector.getValue().firstKeyOf(NodeConnector.class, NodeConnectorKey.class).getId());
coveredMacPaths.add(macPath);
FlowId flowId = new FlowId(String.valueOf(flowIdInc.getAndIncrement()));
FlowKey flowKey = new FlowKey(flowId);
/**
* Path to the flow we want to program.
*/
InstanceIdentifier<Flow> flowPath = InstanceIdentifierUtils.createFlowPath(tablePath, flowKey);
Short tableId = InstanceIdentifierUtils.getTableId(tablePath);
FlowBuilder srcToDstFlow = FlowUtils.createDirectMacToMacFlow(tableId, DIRECT_FLOW_PRIORITY, srcMac, dstMac, destNodeConnector);
srcToDstFlow.setCookie(new FlowCookie(BigInteger.valueOf(flowCookieInc.getAndIncrement())));
dataStoreAccessor.writeFlowToConfig(flowPath, srcToDstFlow.build());
}
}
}
Aggregations