| package net.onrc.onos.core.intent; |
| |
| |
| import java.util.Objects; |
| |
| import net.floodlightcontroller.util.MACAddress; |
| import net.onrc.onos.core.packet.Ethernet; |
| import net.onrc.onos.core.util.FlowEntryMatch; |
| import net.onrc.onos.core.util.IPv4; |
| import net.onrc.onos.core.util.IPv4Net; |
| import net.onrc.onos.core.util.PortNumber; |
| |
| /** |
| * A class to represent the OpenFlow match. |
| * <p> |
| * At the moment, the supported match conditions are: |
| * <ul> |
| * <li>source port |
| * <li>source and destination MAC address |
| * <li>source and destination IP address |
| * </ul> |
| * <p> |
| * TODO: extend this object to allow more match conditions |
| */ |
| |
| public class Match { |
| private static final short IPV4_PREFIX_LEN = 32; |
| protected long sw; |
| protected MACAddress srcMac; |
| protected MACAddress dstMac; |
| protected int srcIp; |
| protected int dstIp; |
| protected long srcPort; |
| |
| /** |
| * Constructor for Ethernet-based matches. |
| * |
| * @param sw switch's DPID |
| * @param srcPort source port on switch |
| * @param srcMac source Ethernet MAC address |
| * @param dstMac destination Ethernet MAC address |
| */ |
| public Match(long sw, long srcPort, |
| MACAddress srcMac, MACAddress dstMac) { |
| this(sw, srcPort, srcMac, dstMac, ShortestPathIntent.EMPTYIPADDRESS, ShortestPathIntent.EMPTYIPADDRESS); |
| } |
| |
| /** |
| * Generic constructor. |
| * |
| * @param sw switch's DPID |
| * @param srcPort source port on switch |
| * @param srcMac source Ethernet MAC address |
| * @param dstMac destination Ethernet MAC address |
| * @param srcIp source IP address |
| * @param dstIp destination IP address |
| */ |
| public Match(long sw, long srcPort, MACAddress srcMac, MACAddress dstMac, |
| int srcIp, int dstIp) { |
| |
| this.sw = sw; |
| this.srcPort = srcPort; |
| this.srcMac = srcMac; |
| this.dstMac = dstMac; |
| this.srcIp = srcIp; |
| this.dstIp = dstIp; |
| } |
| |
| /** |
| * Matches are equal if all object variables are equal. |
| * |
| * @return true if equal, false otherwise |
| */ |
| @Override |
| public boolean equals(Object obj) { |
| if (obj instanceof Match) { |
| Match other = (Match) obj; |
| //TODO: we might consider excluding sw from this comparison |
| if (this.sw != other.sw) { |
| return false; |
| } |
| if (!Objects.equals(srcMac, other.srcMac)) { |
| return false; |
| } |
| if (!Objects.equals(dstMac, other.dstMac)) { |
| return false; |
| } |
| if (srcIp != other.srcIp) { |
| return false; |
| } |
| |
| if (dstIp != other.dstIp) { |
| return false; |
| } |
| if (this.srcPort != other.srcPort) { |
| return false; |
| } |
| return true; |
| } else { |
| return false; |
| } |
| } |
| |
| /** |
| * Converts the Match into a legacy FlowEntryMatch object. |
| * |
| * @return an equivalent FlowEntryMatch object |
| */ |
| public FlowEntryMatch getFlowEntryMatch() { |
| FlowEntryMatch match = new FlowEntryMatch(); |
| if (srcMac != null) { |
| match.enableSrcMac(srcMac); |
| } |
| if (dstMac != null) { |
| match.enableDstMac(dstMac); |
| } |
| if (srcIp != ShortestPathIntent.EMPTYIPADDRESS) { |
| match.enableEthernetFrameType(Ethernet.TYPE_IPV4); |
| IPv4 srcIPv4 = new IPv4(srcIp); |
| IPv4Net srcIP = new IPv4Net(srcIPv4, IPV4_PREFIX_LEN); |
| match.enableSrcIPv4Net(srcIP); |
| } |
| if (dstIp != ShortestPathIntent.EMPTYIPADDRESS) { |
| match.enableEthernetFrameType(Ethernet.TYPE_IPV4); |
| IPv4 dstIPv4 = new IPv4(dstIp); |
| IPv4Net dstIP = new IPv4Net(dstIPv4, IPV4_PREFIX_LEN); |
| match.enableDstIPv4Net(dstIP); |
| } |
| match.enableInPort(new PortNumber((short) srcPort)); |
| return match; |
| } |
| |
| /** |
| * Returns a String representation of this Match. |
| * |
| * @return the match as a String |
| */ |
| @Override |
| public String toString() { |
| return "Sw:" + sw + " (" + srcPort + "," + srcMac + "," + dstMac + "," + srcIp + "," + dstIp + ")"; |
| } |
| |
| /** |
| * Generates hash using Objects.hash() to hash all object variables. |
| * |
| * @return hashcode |
| */ |
| @Override |
| public int hashCode() { |
| //TODO: we might consider excluding sw from the hash function |
| // to make it easier to compare matches between switches |
| return Objects.hash(sw, srcPort, srcMac, dstMac, srcIp, dstIp); |
| } |
| } |