use of org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table in project netvirt by opendaylight.
the class ArpResponderUtil method installFlow.
/**
* Install ARP Responder FLOW.
*
* @param mdSalManager
* Reference of MDSAL API RPC that provides API for installing
* flow
* @param dpnId
* DPN on which flow to be installed
* @param flowId
* Uniquely Identifiable Arp Responder Table flow Id
* @param flowName
* Readable flow name
* @param priority
* Flow Priority
* @param cookie
* Flow Cookie
* @param matches
* List of Match Criteria for the flow
* @param instructions
* List of Instructions for the flow
*/
public static void installFlow(IMdsalApiManager mdSalManager, BigInteger dpnId, String flowId, String flowName, int priority, BigInteger cookie, List<MatchInfo> matches, List<Instruction> instructions) {
Flow flowEntity = MDSALUtil.buildFlowNew(NwConstants.ARP_RESPONDER_TABLE, flowId, priority, flowName, 0, 0, cookie, matches, instructions);
mdSalManager.installFlow(dpnId, flowEntity);
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table 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.flow.inventory.rev130819.tables.Table 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.flow.inventory.rev130819.tables.Table 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.flow.inventory.rev130819.tables.Table in project netvirt by opendaylight.
the class ElanMacTableGet method doExecute.
@Override
protected Object doExecute() {
LOG.debug("Executing elan mac table get command for {}", elanName);
Collection<MacEntry> macTables = elanProvider.getElanMacTable(elanName);
if (!macTables.isEmpty()) {
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yy:HH:mm:ss");
session.getConsole().println(getMacTableHeaderOutput());
session.getConsole().println(elanName);
for (MacEntry mac : macTables) {
boolean isStatic = mac.isIsStaticAddress();
session.getConsole().println(String.format(ElanCLIUtils.MAC_TABLE_CLI_FORMAT, "", mac.getInterface(), mac.getMacAddress().getValue(), ""));
session.getConsole().println(String.format(ElanCLIUtils.MAC_TABLE_CLI_FORMAT, "", isStatic, "", isStatic ? "-" : formatter.format(new Date(mac.getControllerLearnedForwardingEntryTimestamp().longValue()))));
}
}
return null;
}
Aggregations