blob: 07522a0f88292f3ae16af02243d7893131694f9c [file] [log] [blame]
package net.onrc.onos.core.drivermanager;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import net.floodlightcontroller.core.IOF13Switch.NeighborSet.groupPktType;
import net.onrc.onos.core.matchaction.MatchAction;
import net.onrc.onos.core.matchaction.MatchActionOperationEntry;
import net.onrc.onos.core.matchaction.action.Action;
import net.onrc.onos.core.matchaction.action.GroupAction;
import net.onrc.onos.core.matchaction.action.OutputAction;
import net.onrc.onos.core.matchaction.action.PopMplsAction;
import net.onrc.onos.core.matchaction.action.SetDAAction;
import net.onrc.onos.core.matchaction.match.Ipv4Match;
import net.onrc.onos.core.matchaction.match.Match;
import net.onrc.onos.core.matchaction.match.MplsMatch;
import net.onrc.onos.core.util.Dpid;
import net.onrc.onos.core.util.IPv4Net;
import net.onrc.onos.core.util.PortNumber;
import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFOxmList;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthDst;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthType;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv4DstMasked;
import org.projectfloodlight.openflow.types.EthType;
import org.projectfloodlight.openflow.types.IPv4Address;
import org.projectfloodlight.openflow.types.MacAddress;
/**
* OFDescriptionStatistics Vendor (Manufacturer Desc.): Dell Make (Hardware
* Desc.) : OpenFlow 1.3 Reference Userspace Switch Model (Datapath Desc.) :
* None Software : Serial : None
*/
public class OFSwitchImplDellOSR extends OFSwitchImplSpringOpenTTP {
/* Table IDs to be used for Dell Open Segment Routers*/
private static final int DELL_TABLE_VLAN = 17;
private static final int DELL_TABLE_TMAC = 18;
private static final int DELL_TABLE_IPv4_UNICAST = 30;
private static final int DELL_TABLE_MPLS = 25;
private static final int DELL_TABLE_ACL = 40;
private static final int MPLS_SWAP_FLOW = 0x00;
private static final int MPLS_POP_NO_BOS_FLOW = 0x10;
private static final int MPLS_POP_BOS_FLOW = 0x11;
public OFSwitchImplDellOSR(OFDescStatsReply desc, boolean usePipeline13) {
super(desc, usePipeline13);
setVlanTableId(DELL_TABLE_VLAN);
setTmacTableId(DELL_TABLE_TMAC);
setIpv4UnicastTableId(DELL_TABLE_IPv4_UNICAST);
setMplsTableId(DELL_TABLE_MPLS);
setAclTableId(DELL_TABLE_ACL);
}
@Override
protected OFOxmList getIPEntryMatchList(OFFactory ofFactory, Match match) {
/* For Dell Switches, the IP entry match list shall
* also include destination mac matching rule
*/
Ipv4Match ipm = (Ipv4Match) match;
IPv4Net ipdst = ipm.getDestination();
OFOxmEthType ethTypeIp = ofFactory.oxms()
.ethType(EthType.IPv4);
OFOxmEthDst dmac = ofFactory.oxms().ethDst(getRouterMacAddr());
OFOxmIpv4DstMasked ipPrefix = ofFactory.oxms()
.ipv4DstMasked(
IPv4Address.of(ipdst.address().value()),
IPv4Address.ofCidrMaskLength(ipdst.prefixLen())
);
OFOxmList oxmList = OFOxmList.of(ethTypeIp, dmac, ipPrefix);
return oxmList;
}
@Override
protected void setTableMissEntries() throws IOException {
// set all table-miss-entries
populateTableMissEntry(vlanTableId, true, false, false, -1);
populateTableMissEntry(tmacTableId, true, false, false, -1);
populateTableMissEntry(ipv4UnicastTableId, false, true, true,
aclTableId);
populateTableMissEntry(mplsTableId, false, true, true,
aclTableId);
populateTableMissEntry(aclTableId, true, false, false, -1);
}
protected MacAddress getNeighborRouterMacAddress(Dpid ndpid,
groupPktType outPktType) {
if (outPktType == groupPktType.MPLS_OUTGOING)
return getRouterMPLSMac(ndpid);
else
return super.getNeighborRouterMacAddress(ndpid,
groupPktType.IP_OUTGOING);
}
/* Dell Open Segment Router specific Implementation .
* Gets the specified Router's MAC address to be used for MPLS flows
* For Dell OSR, the MPLS MAC is IP MAC + 1
*/
@Override
public MacAddress getRouterMPLSMac(Dpid dpid) {
return MacAddress.of(super.getRouterIPMac(dpid).getLong() + 1);
}
protected void createGroupsAtTransitRouter(Set<Dpid> dpids) {
/* Create all possible Neighbor sets from this router
* NOTE: Avoid any pairings of edge routers only
*/
Set<Set<Dpid>> sets = getPowerSetOfNeighbors(dpids);
sets = filterEdgeRouterOnlyPairings(sets);
log.debug("createGroupsAtTransitRouter: The size of neighbor powerset "
+ "for sw {} is {}", getStringId(), sets.size());
Set<NeighborSet> nsSet = new HashSet<NeighborSet>();
for (Set<Dpid> combo : sets) {
if (combo.isEmpty())
continue;
for (groupPktType gType : groupPktType.values()) {
NeighborSet ns = new NeighborSet();
ns.addDpids(combo);
ns.setOutPktType(gType);
log.debug("createGroupsAtTransitRouter: sw {} combo {} ns {}",
getStringId(), combo, ns);
nsSet.add(ns);
}
}
log.debug("createGroupsAtTransitRouter: The neighborset with label "
+ "for sw {} is {}", getStringId(), nsSet);
for (NeighborSet ns : nsSet) {
updatePortNeighborSetMap(ns);
int gid = createGroupForANeighborSet(ns);
if (gid == -1) {
log.warn("Create Group failed with -1");
}
}
}
protected void analyzeAndUpdateMplsActions(
MatchActionOperationEntry mao) {
MatchAction ma = mao.getTarget();
MplsMatch mplsm = (MplsMatch) ma.getMatch();
int flowType = 0x00;
PortNumber outPort = null;
for (Action action : ma.getActions()) {
if (action instanceof PopMplsAction) {
flowType |= 0x10;
if (mplsm.isBos()) {
flowType |= 0x01;
}
}
else if (action instanceof OutputAction)
outPort = ((OutputAction) action).getPortNumber();
}
groupPktType outPktType = groupPktType.IP_OUTGOING;
if ((flowType == MPLS_SWAP_FLOW) ||
(flowType == MPLS_POP_NO_BOS_FLOW))
outPktType = groupPktType.MPLS_OUTGOING;
for (Action action : ma.getActions()) {
if ((action instanceof GroupAction)
&& (((GroupAction) action).getGroupId() == -1)) {
((GroupAction) action).getDpids().setOutPktType(outPktType);
}
else if (action instanceof SetDAAction) {
if ((outPort != null) &&
(portToNeighbors.get(outPort) != null)) {
Dpid neighborDpid = portToNeighbors.get(outPort);
((SetDAAction) action).setAddress(
getNeighborRouterMacAddress(neighborDpid, outPktType));
}
}
}
}
}